For words of length 0 or 1 there can be no pinching so we simply return the word.
Note that this operation constructs a new word. An optimization is to make the word process destructive to save space. This is not yet implemented.
(defun pinch (word)
"given a word pinch out all inverse elements"
(let ((stack nil) (wlen (- (length word) 1)))
(if (> wlen 0)
(progn
(push (elt word 0) stack)
(dotimes (i wlen)
(cond
((and (eq (first stack) #\\a) (eq (elt word (+ i 1)) #\\A)) (pop stack))
((and (eq (first stack) #\\A) (eq (elt word (+ i 1)) #\\a)) (pop stack))
((and (eq (first stack) #\\b) (eq (elt word (+ i 1)) #\\B)) (pop stack))
((and (eq (first stack) #\\B) (eq (elt word (+ i 1)) #\\b)) (pop stack))
(t (push (elt word (+ i 1)) stack))))
(concatenate 'string (reverse stack)))
word)))