;definitions and theorems about ordinal arithmetic (in-package "ACL2") (include-book "ordinal-addition") (local (include-book "top-with-meta")) (local (disable-forcing)) (local (in-theory (disable o+ o<))) (defthm count1-o< (implies (and (o-p a) (o-p b) (o-p c) (o< c b)) (<= (count1 a b) (count1 a c)))) (defthm o-last-expt-o-first-expt-count (implies (and (o-p a) (o-p b) (o< (o-first-expt b) (o-last-expt a))) (equal (count1 a b) (olen a))) :hints (("goal" :in-theory (enable o-last-expt) :induct (count1 a b)))) (defthm nat-count (implies (and (natp b) (o-p a)) (equal (count1 a b) (olen a)))) (local (defun dropn-induct (n a) (if (or (o-finp a) (zp n)) a (dropn-induct (1- n) (o-rst a))))) (defthm count1-count2 (implies (and (natp n) (<= n (count1 a b)) (o-p a) (o-p b)) (equal (count2 a b n) (count1 a b))) :hints (("goal" :induct (dropn-induct n a)))) (defthm padd-o-first-expt (implies (and (posp n) (o-infp a)) (equal (o-first-expt (padd a b n)) (o-first-expt a)))) (defthm padd-o+ (implies (and (<= q (count1 a b)) (o-p a) (o-p b)) (equal (padd a b q) (o+ a b))) :hints (("goal" :in-theory (enable o+)))) (verify-guards padd) (local (in-theory (disable padd o+ count1 count2 o-))) ;pmult, omul (local (defthm pmult-o* (implies (and (natp n) (<= n (count1 (o-first-expt a) (o-first-expt b))) (o-p a) (o-p b)) (equal (pmult a b n) (o* a b))))) (defthm o*-finite (implies (and (o-finp a) (o-finp b)) (o-finp (o* a b))) :rule-classes ((:type-prescription) (:forward-chaining :trigger-terms ((o* a b))))) (defthm |a0 = 0| (equal (o* a 0) 0)) (defthm |0a = 0| (equal (o* 0 a) 0)) (defthm o-infp-o* (implies (and (not (equal b 0)) (o-infp a) (o-p a) (o-p b)) (o-infp (o* a b))) :rule-classes ((:rewrite :match-free :all) (:forward-chaining :trigger-terms ((o* a b))))) (defthm o-infp-o*-2 (implies (and (not (equal b 0)) (o-infp a) (o-p a) (o-p b)) (o-infp (o* b a))) :rule-classes ((:rewrite :match-free :all) (:forward-chaining :trigger-terms ((o* a b))))) (defthm |a1 = a| (implies (o-p a) (equal (o* a 1) a))) (defthm |1a = a| (implies (o-p a) (equal (o* 1 a) a))) (defthm o*-0 (implies (and (o-p a) (o-p b)) (equal (equal (o* a b) 0) (or (equal a 0) (equal b 0))))) (defthm o*-o-first-expt (implies (and (not (equal a 0)) (not (equal b 0)) (o-p a) (o-p b)) (equal (o-first-expt (o* a b)) (o+ (o-first-expt a) (o-first-expt b))))) (encapsulate ;this encapsulate is here so that o*-o-first-expt-< doesn't interfere with ;any other theorems in the book () (local (defthm o*-o-first-expt-< (implies (and (o-p a) (o-p b) (o-p c) (o< (o-first-expt a) (o-first-expt b))) (o< (o-first-expt (o* c a)) (o+ (o-first-expt c) (o-first-expt b)))) :rule-classes ((:forward-chaining :match-free :all)))) (defthm o-p-o* (implies (and (o-p a) (o-p b)) (o-p (o* a b))) :hints (("goal" :in-theory (enable o*-o-first-expt-<) :induct (o* a b))) :rule-classes ((:rewrite) (:forward-chaining :trigger-terms ((o* a b)))))) (verify-guards pmult) (verify-guards ob*) (defthm |~(a=0) & b>1 <=> a < ab| (implies (and (o-p a) (o-p b)) (equal (o< a (o* a b)) (and (not (equal a 0)) (not (equal b 0)) (not (equal b 1))))) :hints (("goal" :induct (o* a b)))) ; Needed at least for the next lemma. (local (in-theory (enable |a < b => ~(a = b)|))) (defthm |a = ab <=> (a = 0) V (b = 1)| (implies (and (o-p a) (o-p b)) (equal (equal a (o* a b)) (or (equal a 0) (equal b 1)))) :hints (("goal" :cases ((equal a 0) (equal b 0) (equal b 1))))) (defthm |(ab)c = a(bc)| (implies (and (o-p a) (o-p b) (o-p c)) (equal (o* (o* a b) c) (o* a b c)))) (defthm o*-o-first-coeff (implies (and (not (equal a 0)) (o-p a) (o-p b)) (equal (o-first-coeff (o* a b)) (if (o-infp b) (o-first-coeff b) (* (o-first-coeff a) b))))) (defthm o-first-coeff-o*-omega (implies (o-p a) (equal (o-first-coeff (o* (omega) a)) (o-first-coeff a))) :hints (("goal" :cases ((o-infp a))))) (defthm o*-o-rst (implies (and (or (and (o-infp a) (not (equal b 0))) (and (o-infp b) (not (equal a 0)))) (o-p a) (o-p b)) (equal (o-rst (o* a b)) (if (o-infp b) (o* a (o-rst b)) (o-rst a))))) (defthm o*-o-first-expt-< (implies (and (not (equal a 0)) (o< (o-first-expt b) (o-first-expt c)) (o-p a) (o-p b) (o-p c)) (o< (o-first-expt (o* a b)) (o-first-expt (o* a c)))) :rule-classes ((:forward-chaining :trigger-terms ((o< (o-first-expt b) (o-first-expt c)))) (:rewrite :match-free :all))) (encapsulate ; This encapsulate is here to avoid the use of subgoal hints. nil (local (defthm |a(b + c) = ab + ac helper1| (implies (and (o< (o-first-expt c) (o-first-expt b)) (implies (and (o-p a) (o-p (o-rst b)) (o-p c)) (equal (o* a (o+ (o-rst b) c)) (o+ (o* a (o-rst b)) (o* a c)))) (o-p a) (o-p b) (o-p c)) (equal (o* a (o+ b c)) (o+ (o* a b) (o* a c)))) :hints (("goal" :in-theory (enable o+) :use ((:instance o*-o-first-expt-< (c b) (b c))))))) (local (defthm |a(b + c) = ab + ac helper2| (implies (and (o<= (o-first-expt c) (o-first-expt b)) (o<= (o-first-expt b) (o-first-expt c)) (o-p a) (o-p b) (o-p c)) (equal (o* a (o+ b c)) (o+ (o* a b) (o* a c)))) :hints (("goal" :in-theory (enable o+))))) (local (defun o*-ind-1 (a b c) (cond ((equal a 0) (list a b c)) ((and (o-infp b) (o< (o-first-expt c) (o-first-expt b))) (o*-ind-1 a (o-rst b) c)) ((o< (o-first-expt b) (o-first-expt c)) (list a b c)) (t (list a b c))))) (defthm |a(b + c) = ab + ac| (implies (and (o-p a) (o-p b) (o-p c)) (equal (o* a (o+ b c)) (o+ (o* a b) (o* a c)))) :hints (("goal" :induct (o*-ind-1 a b c))))) (defthm |a+(a(b-1)) = ab| (implies (and (not (equal b 0)) (o-p a) (o-p b)) (equal (o+ a (o* a (o- b 1))) (o* a b))) :hints (("goal" :in-theory (e/d (o<) (|a <= b => a+(b-a) = b| |a(b + c) = ab + ac| o*)) :use ((:instance |a(b + c) = ab + ac| (b 1) (c (o- b 1))) (:instance |a <= b => a+(b-a) = b| (a 1)))))) (defthm |a <= b => ac <= bc| (implies (and (o-p a) (o-p b) (o-p c) (o<= a b)) (o<= (o* a c) (o* b c))) :hints (("goal" :in-theory (enable o<)))) (encapsulate ;this encapsulate is here so that the lemmas used to prove ;|(a < b) & ~(c = 0) <=> ca < cb| don't slow down the ;rest of the book () (local (defthm |(a < b) & ~(c = 0) <=> ca < cb :a| (implies (and (o-p a) (o-p b) (o-p c) (o< a b) (not (equal c 0))) (o< (o* c a) (o* c b))) :hints (("goal" :in-theory (enable o<) :induct (o< a b))))) (local (defthm |(a < b) & ~(c = 0) <=> ca < cb :b| (implies (and (o-p a) (o-p b) (o-p c) (o< (o* c a) (o* c b))) (o< a b)) :hints (("goal" :use (:instance |(a < b) & ~(c = 0) <=> ca < cb :a| (b a) (a b))) ("goal'" :cases ((equal a b) (o< a b)))) :rule-classes ((:rewrite :match-free :all)))) (defthm |(a < b) & ~(c = 0) <=> ca < cb| ;a < b => ca < cb (implies (and (o-p a) (o-p b) (o-p c)) (equal (o< (o* c a) (o* c b)) (and (o< a b) (not (equal c 0))))))) (defthm |ab = ac <=> (b=c) V (a = 0)| (implies (and (o-p a) (o-p b) (o-p c)) (equal (equal (o* a b) (o* a c)) (or (equal a 0) (equal b c)))) :hints (("goal" :do-not-induct t :use ((:instance |(a < b) & ~(c = 0) <=> ca < cb| (c a) (a b) (b c)) (:instance |(a < b) & ~(c = 0) <=> ca < cb| (c a) (a c))) :in-theory (disable |(a < b) & ~(c = 0) <=> ca < cb|))) :rule-classes ((:rewrite :match-free :all))) (defthm |(a <= b) & (c < d) => ac < bd| (implies (and (not (equal b 0)) (o<= a b) (o< c d) (o-p a) (o-p b) (o-p c) (o-p d)) (o< (o* a c) (o* b d))) :hints (("goal" :in-theory (disable |a < b & b <= c => a < c|) :use ((:instance |a < b & b <= c => a < c| (a (o* a c)) (b (o* a d)) (c (o* b d))))))) (defthm |(a <= b) & (c <= d) => ac <= bd| (implies (and (not (equal b 0)) (o<= a b) (o<= c d) (o-p a) (o-p b) (o-p c) (o-p d)) (o<= (o* a c) (o* b d))) :hints (("goal" :in-theory (disable |(a <= b) & (c < d) => ac < bd|) :use |(a <= b) & (c < d) => ac < bd|))) (defthm |b a+b < a*c| (implies (and (o<= 2 c) (o< b a) (o-p a) (o-p b) (o-p c)) (o< (o+ a b) (o* a c))) :hints (("goal" :in-theory (disable o*) :use ((:instance |a < b & b <= c => a < c| (a (o+ a b)) (b (o* a 2)) (c (o* a c))) (:instance |a+(a(b-1)) = ab| (b 2)))))) (defthm |(a = 1) & (b = 1) <=> ab = 1| (implies (and (o-p a) (o-p b)) (equal (equal (o* a b) 1) (and (equal a 1) (equal b 1)))) :hints (("goal" :use |~(a=0) & b>1 <=> a < ab| :in-theory (e/d (o<) (|~(a=0) & b>1 <=> a < ab|))))) (defthm o*-1 (implies (and (o-p a) (posp b)) (equal (o+ a (o* a (+ -1 b))) (o* a b))) :hints (("goal" :in-theory (enable o+)))) ;another seemingly obvious theorem that is needed to help acl2 ;reason about equality (defthm make-ord-equal-4 (implies (and (o-infp a) (o-p a) (equal (o-first-coeff a) fca) (equal (o-first-expt a) fea) (equal (o-rst a) rsta)) (equal (make-ord fea fca rsta) a)) :rule-classes ((:rewrite :match-free :all))) (encapsulate () (local (defthm o*-limitp-lemma1 (implies (and (o-infp b) (o-p a) (o-p b)) (o-p (make-ord (o+ (o-first-expt a) (o-first-expt b)) (o-first-coeff b) (o* a (o-rst b))))) :hints (("goal" :cases ((equal a 0) (equal (o-rst b) 0)))))) (defthm o*-limitp-1 (implies (and (o-p b) (not (equal b 0)) (limitp a)) (limitp (o* a b))) :hints (("goal" :in-theory (enable o* natpart)))) (defthm o*-limitp-2 (implies (and (not (equal a 0)) (o-p a) (limitp b)) (limitp (o* a b))))) (defthm o*-o-first-expt-smash-1 (implies (and (equal (o-rst b) 0) (not (equal a 0)) (o-p a) (o-p b) (o< (o-first-expt (o-first-expt a)) (o-first-expt (o-first-expt b)))) (equal (o* a b) b)) :rule-classes ((:forward-chaining :trigger-terms ((o< (o-first-expt (o-first-expt a)) (o-first-expt (o-first-expt b))))))) (defthm o*-o-first-expt-smash-2 (implies (and (not (equal a 0)) (natp a) (limitp b)) (equal (o* a b) b)) :hints (("goal" :in-theory (enable natpart)))) (defthm o*-o-first-expt-smash-1a (implies (and (equal (o-rst b) 0) (not (equal a 0)) (o-p a) (o-p b) (o-p c) (o< (o-first-expt (o-first-expt a)) (o-first-expt (o-first-expt b)))) (equal (o* a b c) (o* b c))) :hints (("goal" :in-theory (disable |(ab)c = a(bc)|) :use ((:instance |(ab)c = a(bc)|))))) (defthm o*-o-first-expt-smash-2a (implies (and (o-finp a) (not (equal a 0)) (o-infp b) (equal (o-rst b) 0) (o-p a) (o-p b) (o-p c)) (equal (o* a b c) (o* b c))) :hints (("goal" :in-theory (disable |(ab)c = a(bc)|) :use ((:instance |(ab)c = a(bc)|))))) (defthm o*-o-first-expt-smash-1b (implies (and (equal (o-rst c) 0) (not (equal b 0)) (o-p a) (o-p b) (o-p c) (o-p d) (o< (o-first-expt (o-first-expt b)) (o-first-expt (o-first-expt c)))) (equal (o* (o* a b) (o* c d)) (o* (o* a c) d))) :hints (("goal" :in-theory (disable o*)))) (defthm o*-o-first-expt-smash-2b (implies (and (o-finp b) (not (equal b 0)) (o-infp c) (equal (o-rst c) 0) (o-p a) (o-p b) (o-p c) (o-p d)) (equal (o* (o* a b) (o* c d)) (o* (o* a c) d))) :hints (("goal" :in-theory (disable o*)))) (defthm o*-len-1 (implies (and (o-p a) (posp b)) (equal (olen (o* a b)) (olen a)))) (defthm o*-len-2 (implies (and (not (equal a 0)) (equal (natpart b) 0) (o-p a) (o-p b)) (equal (olen (o* a b)) (olen b)))) (encapsulate () (local (defthm o*-o-last-expt-l1 (implies (and (not (or (equal a 0) (equal b 0))) (not (and (o-finp a) (o-finp b))) (limitp b) (implies (and (not (equal a 0)) (o-p a) (limitp (o-rst b))) (equal (o-last-expt (o* a (o-rst b))) (o+ (o-first-expt a) (o-last-expt (o-rst b))))) (not (equal a 0)) (o-p a)) (equal (o-last-expt (o* a b)) (o+ (o-first-expt a) (o-last-expt b)))) :hints (("goal" :cases ((o-infp (o-rst b))))) :rule-classes :forward-chaining)) (defthm o*-o-last-expt (implies (and (not (equal a 0)) (o-p a) (limitp b)) (equal (o-last-expt (o* a b)) (o+ (o-first-expt a) (o-last-expt b)))) :hints (("goal" :induct (o* a b) :in-theory (enable o*))))) (defthm o-first-expt-fc-o* (implies (and (equal (o-first-coeff a) (o-first-coeff b)) (equal (o-first-expt a) (o-first-expt b)) (o-p a) (o-p b) (limitp c)) (equal (o* a c) (o* b c))) :rule-classes :forward-chaining) (defthm omega-term-o* (implies (and (o-infp a) (o-p a) (limitp b)) (equal (o* (make-ord (o-first-expt a) 1 0) b) (o* a b)))) (defthm o*-o-finp (implies (and (o-finp a) (o-finp b)) (equal (o* a b) (* a b)))) (defthm o*-o-infp-def (implies (not (equal a 0)) (equal (o* a (make-ord b1 b2 b3)) (make-ord (o+ (o-first-expt a) b1) b2 (o* a b3)))))