Topics ACL2 as a specification language Reasoning about ACL2 programs
Equational reasoning Induction and recursion
ACL2 as a logic ACL2 axioms Definitional axioms and input contracts Induction principle
ACL2 as a theorem prover
Sorting
Given a list L = (L1 … Ln) of elements from a totally ordered set (e.g. rationals with ≤) return a list M = (M1 … Mn) such that
(sorted M), i.e. M1 ≤ M2 ≤ ≤ Mn
M = (permutation L), i.e. Mi = L(i) where is a bijection from {1,…,n} to {1,…,n}
sortedp
Predicate to test to see if a list is sortedShould check to see that L is a list of rationals
(x1 x2 … xn) with x1 ≤ x2 ≤ ≤ xn
xi ≤ xi+1 for 1 ≤ i < n
i xi ≤ xi+1 1 ≤ i i < n
(defun sortedp (L) (cond ((equal L nil) t) ((equal (length L) 1) t) ((and (<= (first L) (second L)) (sortedp (rest L))))))
Correctness of sortedp
L = (x1 x2 … xn)
By induction on len(L)Base cases L nil or of length 1
Show xi ≤ xi+1 for 1 ≤ i < n
x1 ≤ x2 and by induction xi ≤ xi+1 for 2 ≤ i < n
Insertion Sort
; input. L is a list of integers; output is a sorted list of integers whose elements are the same as in L.
(defun insertionsort (L)
(if (equal L nil)
nil
(insert (first L) (insertionsort (rest L)))))
; inputs x is an integer and L is a list of rationals that is sorted; output is a sorted list of integers.(defun insert (x L) (cond ((equal L nil) (list x)) ((<= x (first L)) (cons x L)) ((cons (first L) (insert x (rest L))))))
Testing of Insertion Sort
(check= (insert 1 nil) '(1))(check= (insert 4 '(1 2 3)) '(1 2 3 4))(check= (insert 0 '(1 2 3)) '(0 1 2 3))(check= (insert 2 '(1 3)) '(1 2 3))(check= (sortedp (insert 2 '(1 3))) t)
(check= (insertionsort '(3 2 1)) '(1 2 3))(check= (sortedp (insertionsort '(3 4 2 1))) t)
Correctness of insertionsort
L = (L1 … Ln)
1. (insertionsort L) terminates and returns a list
2. (insertionsort L) is sorted
3. (insertionsort L) is a permutation of L
Proof by induction on n
1. For n 0, recursive call with smaller n
2. Recursive call produces a sorted list of (rest L) by induction and (insert (first L) (insertionsort (rest L))) returns a sorted list (by induction)
3. Recursive call returns a permutation of (rest L) and insert returns a list containing (first L) and elements of (rest L)
Formal Correctness Proof
(defthm insert-sortedp (implies (sortedp L) (sortedp (insert x L))))
(defthm insertion-sort-is-sorted (sortedp (insertion-sort L)))
(defthm insert-perm-cons (implies (perm L P) (perm (insert x L) (cons x P))))
(thm (perm (insertion-sort L) L))
Insertion Sort
(defunc insertion-sort (L) :input-contract (list-rationalp L) :output-contract (and (list-rationalp (insertion-sort L)) (sortedp (insertion-sort L)) (perm (insertion-sort L) L)) (if (equal L nil) nil (insert (first L) (insertion-sort (rest L)))))
insert
(defunc insert (x L) :input-contract (and (rationalp x) (list-rationalp L) (sortedp L)) :output-contract (and (list-rationalp (insert x L)) (sortedp (insert x L)) (perm (insert x L) (cons x L))) (cond ( (equal L nil) (list x) ) ( (<= x (first L)) (cons x L) ) ( (cons (first L) (insert x (rest L))) ) ) )
sortedp
(defunc sortedp (x) :input-contract (list-rationalp x) :output-contract (booleanp (sortedp x)) (cond ( (equal x nil) t ) ( (equal (len x) 1) t ) ( t (and (<= (first x) (second x)) (sortedp (rest x))) ) ))
list-rationalp
(defunc list-rationalp (x) :input-contract t :output-contract (booleanp (list-rationalp x)) (cond ( (equal x nil) t) ( (consp x) (and (rationalp (first x)) (list-rationalp (rest
x))) ) ( t nil) ))
list-rationalp
(defunc sortedp (x) :input-contract (list-rationalp x) :output-contract (booleanp (sortedp x)) (cond ( (equal x nil) t ) ( (equal (len x) 1) t ) ( t (and (<= (first x) (second x)) (sortedp (rest x))) ) ))
perm
(defunc perm (L P) :input-contract (and (list-rationalp L) (list-rationalp P)) :output-contract (booleanp (perm L P)) (cond ( (equal L nil) (equal P nil) ) ( t (and (in (first L) P) (perm (rest L) (del (first L) P))) ) ))
in
(defunc in (x L) :input-contract (and (rationalp x) (list-rationalp L)) :output-contract (booleanp (in x L)) (cond ( (equal L nil) nil ) ( (equal x (first L)) t ) ( t (in x (rest L)) ) ))
del
(defunc del (x L) :input-contract (and (rationalp x) (list-rationalp L)) :output-contract (list-rationalp (del x L)) (cond ( (equal L nil) nil ) ( (equal x (first L)) (rest L) ) ( t (cons (first L) (del x (rest L))) ) ))
How was ACL2 able to do this?
Proofs use formal reasoning Axioms for built-in functions (consp, if, equal) Every time we define a function that ACL2s
admits, we also get a definitional axiom an axiom stating that the function is equal to its body.
I.E. Replace a function call by its body substituting the formal parameters with the arguments
Reason using properties of first order logic Equational reasoning Well founded induction
Example
Reason about the following functions
(defunc len (x)
:input-contract t
:output-contract (natp (len x))
(if (atom x)
0
(+ 1 (len (rest x)))))
Example
(defunc atom (x)
:input-contract t
:output-contract (booleanp (atom x))
(not (consp x)))
(defunc not (a)
:input-contract (booleanp a)
:output-contract (booleanp (not a))
(if a nil t))
Example
Theorem: (equal (len (cons x (list z))) 2) (len (cons x (list z))) (if (atom (cons x (list z))) 0 (+ 1 (len (rest (cons
x (list z)))))) {def of len} (if (atom (cons x (list z))) 0 (+ 1 (len (list z))))
{first-rest axiom} (if (not (consp (cons x (list z)))) 0 (+ 1 (len (list
z)))) {def of atom}
Example Continued (if (if (consp (cons x (list z))) nil t) 0 (+ 1 (len (list
z)))) {def of not} (if (if t nil t) 0 (+ 1 (len (list z)))) {consp axiom} (if nil 0 (+ 1 (len (list z)))) {if axiom} (+ 1 (len (list z))) {if axiom} (+ 1 (len (cons z nil))) {expand list macro} … (+ 1 1) = 2 (equal 2 2) = t
Example Proof
Conjecture: (equal (len (cons x (list z)))(len (cons y (list z))))
The previous theorem showed (len (cons x (list z))) = 2
Similar reasoning shows (len (cons y (list z))) = 2
Alternatively we can substitute x=y in the theorem to obtain (len (cons y (list z))) = 2
Counter Example
Same type of reasoning can be use to prove conjectures false
Conjecture: (equal (len (list x)) (len x))(equal (len (list nil)) (len nil))
Compute (len nil) and (len (list nil)) and compare
Counter Example(len nil) (if (atom nil) 0 (+ 1 (len (rest nil))))) [def of len](if t 0 (+ 1 (len (rest nil))))) [def of atom]0 [if axiom](len (list nil))(if (atom (list nil)) 0 (+ 1 (len (rest (list nil))))))
[def of len](if nil 0 (+ 1 (len (rest nil))))) [def of atom](+ 1 (len (rest nil)))) [if axiom]
Counter Example
(len (list nil))(if (atom (list nil)) 0 (+ 1 (len (rest (list
nil)))))) [def of len](if nil 0 (+ 1 (len (rest (list nil))))) [def of
atom](+ 1 (len (rest (list nil))))) [if axiom](+ 1 (len nil)) [first-rest axiom](+ 1 0) [previous calculation]1 0
List ProcessingRecursive Definition
List := nil | (cons All List)List<Type> := nil (cons Type List<Type>)Process lists using these two cases and use
recursion to recursively process lists in consUse first and rest to access components of cons
Size is the number of conses (generally number of constructors)Prove properties by inducting on size – assume
property holds for smaller size objects and show that this implies it holds for object at hand27
Append
(defun append (x y)
(if (equal x nil)
y
(cons (first x) (append (rest x) y))))
Properties1. (append x nil) = x
2. (length (append x y)) = (+ (length x) (length y))
3. (append x (append y z)) = (append (append x y) z)
28
Structural Induction
When using induction on recursively defined data structures like lists you can induct on the size of the data structure = to the number of calls to the constructors.
When trying to show a property for a data structure of a given size, you can assume that the property holds when making a recursive call on a smaller data structure. You must make sure that the property holds for all constructors including base cases.
With lists (rest …) will return a smaller data structure (at least one fewer cons)
Structural induction allows you to induct on the recursive data structure without being explicit about the size provided the IH is applied to smaller objects.
Proof of Property 1
Show (append x nil) = x using structural induction
Base case. x = nil. In this case, (append nil nil) returns nil = x.
By induction assume recursive call satisfies the property [note (rest x) is smaller than x]I.E. (append (rest x) nil) = (rest x)
Thus (append x nil) returns (cons (first x) (rest x)) = x
Proof of Property 2
Show (length (append x y) = (+ (length x) (length y)) using structural induction on xBase case. x = nil. (append nil y) = y and
(length y) = (+ (length nil) (length y))By induction assume recursive call satisfies the
property (length (append (rest x) y) = (+ (length (rest x))
(length y))
Thus (length (append x y)) = (length (cons (first x) (append (rest x) y)) = (+ 1 (length (rest x)) + (length y)) = (+ (length x) (length y))
Proof of Property 3
Show (append x (append y z)) = (append (append x y) z)Base case. x = nil. (append nil (append y z)) =
(append y z) = (append (append nil y) z) Assume property holds for (rest x)
(append (append x y) z) =(append (cons (first x) (append (rest x) y)) z) [by def]=(cons (first x) (append (append (rest x) y) z)) [by def]=(cons (first x) (append (rest x) (append y z))) [by IH]=(append (cons (first x) (rest x)) (append y z)) [by def]=(append x (append y z)) [by property of cons]
Logical Axioms
Propositional Axiom Schema: ( ) Expansion: derive (1 2) from 2
Contraction: derive from ( ) Associativity: derive (1 2) 3 from 1
(2 3)
Cut: derive (2 3) from (1 2) (1 3) -Introduction: If x not free in B then derive
x A B from A B
Instantiation
Derive | from . That is, if is a theorem and is a substitution, then by instantiation, | is a theorem. Substitution ((var1 term1) . . . (varn termn))
Example. From the theorem (equal (first (cons x y)) x)
We can derive (equal (first (cons (foo x) (bar z))) (foo x))
Equality
Reflexivity Axiom: x=x Equality Axiom: [(x1 = y1 x∧ 2 = y2)] [(x1 = x2)
(y1 = y2)] Implies = is an equivalence relation
Reflexive x = x Symmetric x = y y = x Transitive x = y y = z x = z
Equality Axiom Schema for Functions (x1 = y1 ∧ x∧ n = yn) (f x⇒ 1 xn) = (f y1 yn)
Sound and Complete
Allows use of classic results (derived rules) from logic Propositional tautology Case analysis
Derive from (1 n) and i
Substitution of equals for equals If 1 = 2 then in any formula we may replace 1 by 2
in Deduction law
May assume hypotheses of formula as givens while trying to prove conclusion
Proof of Soundness and Completeness
Show equivalent to natural deductionDerive 2 from 1 and 1 2
1. 1 Given
2. 1 2 Given
3. 2 1 Expansion 1
4. 1 2 Commutativity of [must show]
5. 2 2 Cut 4,2
6. 2 Contraction 5
Axioms of ACL2
x = nil (if x y z) = z⇒ x nil (if x y z) = y⇒ x = y (⇒ equal x y) = t x y (equal x y) = nil⇒ (equal (first (rest x y)) x) nil
t nil (equal x y) = t x = y (equal x y) = nil x y (first (cons x y)) = x
Propositional Functions
(not p) = (if p nil t) (or p q) = (if p t (if q t nil)) (and p q) = (if p (if q t nil) nil) (implies p q) = (if p (if q t nil) t) (iff p q) = (if p (if q t nil) (if q nil t))
(not p) (p nil) (or p q) (p nil) (q nil) (and p q) (p nil) (q nil) (implies p q) (p nil) (q nil)
Remaining Axioms
(rest (cons x y)) = y (consp (cons x y)) = t
Axiomatize other data types symbol, number, characters, strings (implies (consp x) (not (symbolp x)) [disjoint] Derive (consp nil) = nil Axioms from arithmetic – rationals are an
ordered field for constants 0, 1 and +,-,*,/, and <
Definition of Append
(defunc app (a b)
:input-contract (and (listp a) (listp b))
:output-contract (and (listp (app a b))
(equal (len (app a b))
(+ (len a) (len b))))
(if (endp a)
b
(cons (first a) (app (rest a) b))))
Necessary Functions
(defunc listp (l)
:input-contract t
:output-contract (booleanp (listp l))
(if (consp l)
(listp (rest l))
(equal l ())))
(defunc endp (a)
:input-contract (listp a)
:output-contract (booleanp (endp a))
(equal a nil))
Proving Properties
Associativity of app (app x (app y z)) = (app (app x y) z) Definitional axiom Input contracts and context Formal reasoning needed for induction Base Case when x = nil
(endp x) (listp x) (listp y) (listp z) ⇒(app (app x y) z) = (app x (app y z))
General case assuming inductive hypothesis (listp (rest x)) (listp y) (listp z) ∧ ∧ ⇒
(app (app (rest x) y) z) = (app (rest x) (app y z))
Definitional Axiom
(listp a) (listp b)∧
⇒ (app a b)
=
(if (endp a)
b
(cons (first a) (app (rest a) b)))
Can’t expand body unless (listp a) and (listp b)
In general every time we “successfully admit a function” we get an axiom: ic (f x⇒ 1 ... xn) = body
Can’t expand body unless ic is satisfied.
Application of Append
Theorem [CA]: (listp y) (listp z) (app (cons x y) z) = (cons x (app y z)) (app (cons x y) z) (if (endp (cons x y)) z (cons (first (cons x y))
(app (rest (cons x y)) z))) [def of app and inst] (if nil z (cons (first (cons x y)) (app (rest (cons x
y)) z))) [def of endp and consp axiom] (cons (first (cons x y)) (app (rest (cons x y)) z))
[if axiom] (cons x (app y z)) [axioms for first and rest]
Conjecture Contract Checking
Make sure all hypotheses are present in your conjectures
Conjecture: (endp x) ⇒ (app (app x y) z) = (app x (app y z))
Taking into account all input contracts Conjecture: (endp x) (listp x) (listp y)
(listp z) ⇒ (app (app x y) z) = (app x (app y z))
Context
Conjecture: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) (implies (and (endp x) (listp x) (listp y) (listp z))
(iff (app (app x y) z) (app x (app y z))
hyp1 hyp∧ 2 ∧ hyp∧ n conc⇒ Context = {hyp1, hyp2,…, hypn}
Context of conjecture = {(endp x), (listp x), (listp y), (listp z)}
Implications of Context
Conjecture: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z))
C1. (endp x)C2. (listp x)C3. (listp y)C4. (listp z)C5. x = nil {C1, C2}
Testing Conjecture(let ((x nil)
(y nil)
(z nil))
(implies (and (endp x)
(listp x)
(listp y)
(listp z))
(equal (app (app x y) z)
(app x (app y z)))))
Testing Conjecture(test?
(implies (and (endp x)
(listp x)
(listp y)
(listp z))
(equal (app (app x y) z)
(app x (app y z)))))
Proof of Conjecture
Theorem: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z))
C1. (endp x)C2. (listp x)C3. (listp y)C4. (listp z)C5. x = nil {C1, C2}
(app (app x y) z)(app y z) [def of app, def of endp, C5, if axiom] (app x (app y z) ) [def of app, def of endp, C5, if axiom]
General Case
Theorem. [(consp x) (listp x) (listp y) ∧ ∧(listp z)
[(listp (rest x)) (listp y) (listp z)∧ ∧ ⇒ (app (app (rest x) y) z) = (app (rest
x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z))
Rearranging Contexts(consp x)
⇒
[[(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
⇒ [(listp x) (listp y) (listp z)∧ ∧
⇒ (app (app x y) z) = (app x (app y z))]]
[(consp x) [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
⇒ [(listp x) (listp y) (listp z)∧ ∧
⇒ (app (app x y) z) = (app x (app y z))]]
Rearranging Contexts
[(consp x) [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
⇒ [(listp x) (listp y) (listp z)∧ ∧
⇒ (app (app x y) z) = (app x (app y z))]]
[(consp x) (listp x) (listp y) (listp z) ∧ ∧ [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]]
⇒ (app (app x y) z) = (app x (app y z))
Context of Conjecture
Conjecture: (app (app x y) z) = (app x (app y z))
C1. (consp x)C2. (listp x)C3. (listp y)C4. (listp z)
C5. [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
Extending Context
C1. (consp x)C2. (listp x)C3. (listp y)C4. (listp z)
C5. [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
C6. (listp (rest x)) [C1, C2, def of listp]C7. (app (app (rest x) y) z) = (app (rest x) (app y z))
[C6, C3, C4, C5, MP]
Proof of Theorem Theorem. [(consp x) (listp x) (listp y) (listp z) ∧ ∧ [(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]]
⇒ (app (app x y) z) = (app x (app y z))
Proof (app (app x y) z) (app (cons (first x) (app (rest x) y)) z) [def app, C1, C2, C3] (cons (first x) (app (app (rest x) y) z)) [Thm CA,C3,C4,C6] (cons (first x) (app (rest x) (app y z))) [C7] (app x (app y z))) [def app, C1, C2, C3, C4]
Induction Scheme Base Case
(endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z))
Induction Step [(consp x) (listp x) (listp y) (listp z) ∧ ∧
[(listp (rest x)) (listp y) (listp z)∧ ∧
⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z))
Conclude (assuming termination) (app (app x y) z) = (app x (app y z))
Induction in ACL2ACL2 >QUERY (thm (implies (and (true-listp x) (true-listp y) (true-listp z)) (equal (app (app x y) z) (app x (app y z)))))
<< Starting proof tree logging >>^^^ Checkpoint Goal ^^^
*1 (the initial Goal, a key checkpoint) is pushed for proof by induction.
Perhaps we can prove *1 by induction. Five induction schemes are suggested
by this conjecture. These merge into three derived induction schemes.However, two of these are flawed and so we are left with one viablecandidate.
We will induct according to a scheme suggested by (APP X Y). Thissuggestion was produced using the :induction rules APP-INDUCTION-
SCHEME,APP-INDUCTION-SCHEME-FROM-DEFINITION and TRUE-LISTP. If we let
(:P X Y Z)denote *1 above then the induction scheme we'll use is(AND (IMPLIES (NOT (AND (TRUE-LISTP X) (TRUE-LISTP Y))) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (NOT (ENDP X)) (:P (CDR X) Y Z)) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (ENDP X)) (:P X Y Z))).This induction is justified by the same argument used to admit APP.When applied to the goal at hand the above induction scheme producesthree nontautological subgoals.^^^ Checkpoint *1 ^^^Subgoal *1/3Subgoal *1/3'Subgoal *1/2Subgoal *1/1Subgoal *1/1'
*1 is COMPLETED!Thus key checkpoint Goal is COMPLETED!
Q.E.D.
SummaryForm: ( THM ...)Rules: ((:DEFINITION APP-DEFINITION-RULE) (:DEFINITION ENDP) (:DEFINITION NOT) (:DEFINITION TRUE-LISTP) (:EXECUTABLE-COUNTERPART CONSP) (:FAKE-RUNE-FOR-TYPE-SET NIL) (:INDUCTION APP-INDUCTION-SCHEME) (:INDUCTION APP-INDUCTION-SCHEME-FROM-DEFINITION) (:INDUCTION TRUE-LISTP) (:REWRITE APP-CONTRACT) (:REWRITE CAR-CONS) (:REWRITE CDR-CONS) (:REWRITE LIST::TRUE-LISTP-OF-CONS) (:REWRITE LIST::TRUE-LISTP-OF-NON-CONSP))Time: 0.37 seconds (prove: 0.19, print: 0.00, proof tree: 0.03, other:
0.16)Prover steps counted: 10932
Proof succeeded.
Induction in ACL2We will induct according to a scheme suggested by (APP X Y). Thissuggestion was produced using the :induction rules APP-INDUCTION-
SCHEME,APP-INDUCTION-SCHEME-FROM-DEFINITION and TRUE-LISTP. If we let
(:P X Y Z)denote *1 above then the induction scheme we'll use is(AND (IMPLIES (NOT (AND (TRUE-LISTP X) (TRUE-LISTP Y))) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (NOT (ENDP X)) (:P (CDR X) Y Z)) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (ENDP X)) (:P X Y Z))).
Induction in ACL2This induction is justified by the same argument used to admit APP.When applied to the goal at hand the above induction scheme producesthree nontautological subgoals.^^^ Checkpoint *1 ^^^Subgoal *1/3Subgoal *1/3'Subgoal *1/2Subgoal *1/1Subgoal *1/1'
*1 is COMPLETED!Thus key checkpoint Goal is COMPLETED!
Q.E.D.
Induction in ACL2SummaryForm: ( THM ...)Rules: ((:DEFINITION APP-DEFINITION-RULE) (:DEFINITION ENDP) (:DEFINITION NOT) (:DEFINITION TRUE-LISTP) (:EXECUTABLE-COUNTERPART CONSP) (:FAKE-RUNE-FOR-TYPE-SET NIL) (:INDUCTION APP-INDUCTION-SCHEME) (:INDUCTION APP-INDUCTION-SCHEME-FROM-DEFINITION) (:INDUCTION TRUE-LISTP) (:REWRITE APP-CONTRACT) (:REWRITE CAR-CONS) (:REWRITE CDR-CONS) (:REWRITE LIST::TRUE-LISTP-OF-CONS) (:REWRITE LIST::TRUE-LISTP-OF-NON-CONSP))Time: 0.37 seconds (prove: 0.19, print: 0.00, proof tree: 0.03, other: 0.16)Prover steps counted: 10932Proof succeeded.
Exercise
(defun reverse (l)
(if (equal l nil)
nil
(append (reverse (rest l)) (cons (first l) nil))))
Prove the following properties using induction (length (reverse x)) = (length x) (reverse (append x y)) = (append (reverse y) (reverse x)) (reverse (reverse x)) = x
Prove these properties using ACL2
64
Top Related