There are 2 common approaches of guiding ACL2 to a successful proof.
But before I start, do the following: Vertically split the ACL2s workpane i.e. drag the session window all the way toward the right,
and when a line appears in the middle, release the mouse button. This way you have the hw6.lisp on the left pane and hw6.lisp.a2s in the right pane.
Also have the proof-tree view open. Minimize the outline view to get extra space.
-
Approach 1(Using ACL2 as an automatic prover)
-
- Submit the conjecture(defthm form).
- Look at the failed proof attempt on the right. Click in the proof-tree, the first checkpoint(blue). But for hwk6, instead look at the first checkpoint after an INDUCT if it exists.
- Study the checkpoint formula. Look at the conclusion, you want to make it true. If you think it is true without requiring any hypotheses, then make that your lemma(make it general).
Otherwise, look at the hypotheses, pick ones that help determining that the conclusion is obviously true and come up with a general lemma, this will help ACL2 get past this checkpoint.
- Prove the Lemma. If ACL2 could not prove it, then go to step 1 and try to prove it, otherwise repeat the above process for the original conjecture, till ACL2 gets past all its checkpoints and completes the proof.
ACL2 Hint: If the checkpoint is a FERTilize or GENeralize, then let ACL2 do the work for you and look at next goal it produces, for example in proving rev*-rev, the goal produced after Subgoal *1/2'4'(FERT) i.e
Subgoal *1/2'5' is more helpful:
(EQUAL (REV*-ACC A2 (LIST A1))
(APP (REV*-ACC A2 NIL) (LIST A1))).
ACL2 directly gives you the lemma you had come up in class:
(equal (rev*-acc a2 acc)
(app (rev a2) acc))
Note the generalization. Strive to come up with general lemmas, look at the high-level structure of function calls. For example in the above, it made sense to replace (list A1) with a new variable name, say Z (acc is also fine).
Hide irrelevant details and low-level function calls by replacing them uniformly with new variable names. Remember that generalization is the dual of instantiation. Think of a general lemma which when instantiated will help ACL2
get past the checkpoint it is stuck in.
-
Approach 2 (Guiding ACL2, by first coming up with a high-level proof)
-
- Come up with high-level proof steps. Write down the main lemmas you think ACL2 would need.
- Submit these lemmas. Repeat the process for each unsuccessful lemma.
- Submit the conjecture.
- Look at the failed proof-output, and see where ACL2 deviated from your high-level proof steps.
Did ACL2 use a different induction scheme? If yes, you have 2 choices, either give it an explicit induction proof,
or redo your paper-pencil or mental high-level proof using this induction scheme and repeat.
Does ACL2 still need some low-level lemmas missing from your high-level proof? If yes, then identify them and prove those lemmas.
- Guide ACL2 by using hints. Sometimes disabling some previously proven lemmas which are irrelevant to the current proof helps.
For this assignment, I suggest you use Approach 1 and learn to look at the checkpoints in the failed proof output
and coming up with general lemmas that would help ACL2 get past this checkpoints towards a successful proof.
But remember in general Approach 2 is very useful in cases where the failed checkpoint output provides little help in
deciding the lemma to prove. For example in the rev-rev* proof, when you try to prove the above lemma, you get stuck,
if we look at the checkpoint right after FERT we notice:
Subgoal *1/2'5'
(EQUAL (APP (REV L2) (CONS L1 ACC))
(APP (APP (REV L2) (LIST L1)) ACC))
Can you from this checkpoint, decide that all you need is the app-is-associative lemma? If you can, very good, but if you remember, the paper-pencil proof for this is short and the app-is-associative lemma falls right out of that proof.
This was a little specific to Homework 6, to look at the approach suggested by the authors of ACL2, then check out The Method.