I'm trying to model natural numbers in unary notation (O
, (S O)
, (S (S O))
, ...) in ACL2 and prove commutativity of addition. Here is my attempt:
; a NATURAL is 'O or a list ('S n') where n' is a NATURAL
(defun naturalp (n)
(cond ((equal n 'O) t)
(t (and (true-listp n)
(equal (length n) 2)
(equal (first n) 'S)
(naturalp (second n))))))
(defun pred (n)
(cond ((equal n 'O) 'O)
((naturalp n) (second n))))
(defun succ (n)
(list 'S n))
(defun plus (n m)
(cond ((equal n 'O) m)
((naturalp n) (succ (plus (pred n) m)))))
; FIXME: cannot prove this because rewriting loops...
(defthm plus_comm
(implies (and (naturalp n) (naturalp m))
(iff (equal (plus n m) (plus m n)) t)))
This is probably not the most LISPy way of doing this, I'm used to languages with pattern matching.
My problem is as suggested by the comment: The prover loops, trying to prove more and more deeply nested versions of the same thing. How do I stop this? The manual does briefly mention looping rewrite rules, but it doesn't say anything about what to do about them.
My expectation was that this proof would fail, giving me hints as to what auxiliary lemmas are needed to complete it. Can I use the output from the looping proof to figure out a lemma that might stop the looping?