1
; Copyright (C) 2014, ForrestHunt, Inc.
3
; License: A 3-clause BSD license. See the LICENSE file distributed with ACL2.
5
; (certify-book "if-tracker")
7
; IF-TRACKER Normalization
11
; We introduce IF-TRACKER as a constrained function with the property:
13
; (equal (if-tracker rtests (if a b c))
15
; (if-tracker (cons a rtests) b) ; (HIDE a)!
16
; (if-tracker (cons (not a) rtests) c))) ; (HIDE (not a))!
18
; Of course, if this were a rewrite rule, the a and the (not a) in the first
19
; arguments of the IF-TRACKER terms would be immediately rewritten to T and NIL
20
; (assuming a is Boolean) because of the governing test on a. Thus, in actual
21
; applications, we HIDE those two terms.
23
; However, in the course of simplifying IF-TRACKER terms we sometimes produce
26
; (IF-TRACKER rtests (foo (bar (IF a b c))))
28
; where the IF is buried and thus the rule above is not applied.
30
; We wish to lift the IFs out of the second argument of IF-TRACKER and then
31
; apply the IF-TRACKER property (with the indicated terms hidden). We do this
32
; with a metafunction. The metafunction is not very efficient, but is easily
39
(encapsulate ((if-tracker (rtests term) t))
40
(local (defun if-tracker (rtests term)
41
(declare (ignore rtests term))
43
(defthm if-tracker-ignores-rtests
44
(implies (syntaxp (not (quotep rtests)))
45
(equal (if-tracker rtests term)
46
(if-tracker nil term)))))
48
(defun find-first-test (flg x)
53
((eq (ffn-symb x) 'IF)
54
(let ((temp (find-first-test t (fargn x 1))))
55
(cond ((null temp) (fargn x 1))
57
(t (find-first-test nil (fargs x))))
59
(t (or (find-first-test t (car x))
60
(find-first-test nil (cdr x)))))))
62
(defun reduce-if-with-test (flg test val x)
64
(cond ((variablep x) x)
66
((and (eq (ffn-symb x) 'IF)
67
(equal (fargn x 1) test))
69
(reduce-if-with-test t test val (fargn x 2))
70
(reduce-if-with-test t test val (fargn x 3))))
72
(reduce-if-with-test nil test val (cdr x)))))
74
(t (cons (reduce-if-with-test t test val (car x))
75
(reduce-if-with-test nil test val (cdr x)))))))
77
(defun lift-first-test-through-if-tracker (term)
79
((and (not (variablep term))
81
(eq (ffn-symb term) 'IF-TRACKER))
82
(let ((a (find-first-test t (fargn term 2)))
83
(rtests-term (fargn term 1)))
88
(list 'CONS (list 'HIDE a) rtests-term)
89
(reduce-if-with-test t a t (fargn term 2)))
92
(list 'HIDE (list 'NOT a))
94
(reduce-if-with-test t a nil (fargn term 2)))))
98
(defevaluator if-tracker-evl if-tracker-evl-lst
102
(IF-TRACKER rtests term)
105
(defthm reduce-if-with-test-correct
106
(and (implies (and flg
108
(iff (if-tracker-evl test a) val))
109
(equal (if-tracker-evl (reduce-if-with-test flg test val x)
111
(if-tracker-evl x a)))
112
(implies (and (not flg)
113
(pseudo-term-listp x)
114
(iff (if-tracker-evl test a) val))
115
(equal (if-tracker-evl-lst (reduce-if-with-test flg test val x)
117
(if-tracker-evl-lst x a))))
119
:in-theory (enable IF-TRACKER-EVL-CONSTRAINT-0)
120
:induct (reduce-if-with-test flg test val x))))
122
(defthm lift-first-test-through-if-tracker-correct
123
(implies (pseudo-termp x)
124
(equal (if-tracker-evl x a)
125
(if-tracker-evl (lift-first-test-through-if-tracker x) a)))
126
:hints (("Goal" :expand ((:free (x) (hide x)))))
127
:rule-classes ((:meta :trigger-fns (if-tracker))))
129
(in-theory (disable if-tracker-ignores-rtests))
135
; Pretend this is the step function on an IFEQ, where the pc is (car x) and the
138
(cons (if (equal (car (cdr x)) 0) (+ 1 (car x)) (+ 2 (car x)))
139
(if (evenp (car (cdr x)))
143
(thm (implies (and (integerp (car x))
144
(integerp (car (cdr x))))
145
(if-tracker nil (car (steppe x))))