on master help sign in
Merge pull request #4818 from nickdrozd/proofs

Simplify some Nat proofs

commit3d83aa034540571b074498bc8171d8aaf5749325 authorNiklas Larsson <metaniklas@gmail.com> dateSat 29 Feb 2020, 14:19 (7 years ago) parent10b7fe81653d3e
2 files changed+146−112
libs/contrib/Data/Nat/Parity.idr+123−69 libs/prelude/Prelude/Nat.idr+23−43
libs/contrib/Data/Nat/Parity.idr+123−69
@@ -2,18 +2,9 @@ module Data.Nat.Parity
22
33%access public export
44
5−--------------------------------------------------------------------------------
6−-- Parity
7−--------------------------------------------------------------------------------
5+----------------------------------------
86
9−mutual
10− even : Nat -> Bool
11− even Z = True
12− even (S k) = odd k
13−
14− odd : Nat -> Bool
15− odd Z = False
16− odd (S k) = even k
7+-- Type-level, constructive definitions of parity.
178
189||| A nat is Even when it is twice some other nat.
1910Even : Nat -> Type
@@ -23,6 +14,8 @@ Even n = (half : Nat ** n = half * 2)
2314Odd : Nat -> Type
2415Odd n = (haf : Nat ** n = S $ haf * 2)
2516
17+----------------------------------------
18+
2619||| Two more than an Even is Even.
2720add2Even : Even n -> Even (2 + n)
2821add2Even (half ** pf) = (S half ** cong {f = (+) 2} pf)
@@ -52,20 +45,73 @@ succDoublePredPred {k = S _} prf = cong {f = Nat.pred} prf
5245predEvenOdd : Even (S n) -> Odd n
5346predEvenOdd (half ** pf) = (pred half ** succDoublePredPred pf)
5447
48+----------------------------------------
49+
50+-- Boolean definitions of parity.
51+
52+mutual
53+ even : Nat -> Bool
54+ even Z = True
55+ even (S k) = odd k
56+
57+ odd : Nat -> Bool
58+ odd Z = False
59+ odd (S k) = even k
60+
61+----------------------------------------
62+
63+-- The boolean and type-level definitions are equivalent in the sense
64+-- that a proof of one can be gotten from a proof of the other.
65+
66+mutual
67+ ||| Evens are even.
68+ evenEven : Even n -> even n = True
69+ evenEven {n = Z} _ = Refl
70+ evenEven {n = S _} pf = oddOdd $ predEvenOdd pf
71+
72+ ||| Odds are odd.
73+ oddOdd : Odd n -> odd n = True
74+ oddOdd {n = Z} (_ ** pf) = absurd pf
75+ oddOdd {n = S _} pf = evenEven $ predOddEven pf
76+
77+mutual
78+ ||| If it's even, it's Even.
79+ evenEvenConverse : even n = True -> Even n
80+ evenEvenConverse {n = Z} prf = (0 ** Refl)
81+ evenEvenConverse {n = S k} prf =
82+ let (haf ** pf) = oddOddConverse prf in
83+ (S haf ** cong pf)
84+
85+ ||| If it's odd, it's Odd
86+ oddOddConverse : odd n = True -> Odd n
87+ oddOddConverse {n = Z} prf = absurd prf
88+ oddOddConverse {n = S k} prf =
89+ let (half ** pf) = evenEvenConverse prf in
90+ (half ** cong pf)
91+
92+----------------------------------------
93+
94+||| Every nat is either even or odd.
95+evenorodd : (n : Nat) -> Either (even n = True) (odd n = True)
96+evenorodd Z = Left Refl
97+evenorodd (S k) = case evenorodd k of
98+ Left l => Right l
99+ Right r => Left r
100+
55101||| Every nat is either Even or Odd.
56102evenOrOdd : (n : Nat) -> Either (Even n) (Odd n)
57−evenOrOdd Z = Left (0 ** Refl)
58−evenOrOdd (S k) = case evenOrOdd k of
59− Left (half ** pf) => Right (half ** cong {f = S} pf)
60− Right (haf ** pf) => Left (S haf ** cong {f = S} pf)
103+evenOrOdd n = case evenorodd n of
104+ Left e => Left $ evenEvenConverse e
105+ Right o => Right $ oddOddConverse o
106+
107+||| No nat is both even and odd.
108+notevenandodd : even n = True -> odd n = True -> Void
109+notevenandodd {n = Z} en on = absurd on
110+notevenandodd {n = S _} en on = notevenandodd on en
61111
62112||| No nat is both Even and Odd.
63113notEvenAndOdd : Even n -> Odd n -> Void
64−notEvenAndOdd {n = Z} _ (_ ** odd) = absurd odd
65−notEvenAndOdd {n = (S k)} (half ** even) (haf ** odd) =
66− notEvenAndOdd {n = k}
67− (haf ** cong {f = Nat.pred} odd)
68− (pred half ** succDoublePredPred even)
114+notEvenAndOdd en on = notevenandodd (evenEven en) (oddOdd on)
69115
70116||| Evenness is decidable.
71117evenDec : (n : Nat) -> Dec $ Even n
@@ -79,42 +125,46 @@ oddDec n = case evenOrOdd n of
79125 Left even => No $ notEvenAndOdd even
80126 Right odd => Yes odd
81127
82−mutual
83− ||| Evens are even.
84− evenEven : Even n -> even n = True
85− evenEven {n = Z} _ = Refl
86− evenEven {n = S _} pf = oddOdd $ predEvenOdd pf
128+----------------------------------------
87129
88− ||| Odds are odd.
89− oddOdd : Odd n -> odd n = True
90− oddOdd {n = Z} (_ ** pf) = absurd pf
91− oddOdd {n = S _} pf = evenEven $ predOddEven pf
130+||| An Odd is the successor of an Even.
131+oddSuccEven : Odd n -> (m : Nat ** (n = S m, Even m))
132+oddSuccEven (haf ** pf) = (haf * 2 ** (pf, (haf ** Refl)))
92133
93134||| Even plus Even is Even.
94135evenPlusEven : Even j -> Even k -> Even (j + k)
95136evenPlusEven (half_j ** pf_j) (half_k ** pf_k) =
96− rewrite pf_j in
97− rewrite pf_k in
98− (half_j + half_k **
137+ (half_j + half_k **
138+ rewrite pf_j in
139+ rewrite pf_k in
99140 sym $ multDistributesOverPlusLeft half_j half_k 2)
100141
101−||| Odd plus Odd is Even.
102−oddPlusOdd : Odd j -> Odd k -> Even (j + k)
103−oddPlusOdd (haf_j ** pf_j) (haf_k ** pf_k) =
104− rewrite pf_j in
105− rewrite pf_k in
106− rewrite sym $ plusSuccRightSucc (haf_j * 2) (haf_k * 2) in
107− rewrite sym $ multDistributesOverPlusLeft haf_j haf_k 2 in
108− (S (haf_j + haf_k) ** Refl)
142+||| Odd plus Even is Odd.
143+oddPlusEven : Odd j -> Even k -> Odd (j + k)
144+oddPlusEven oj ek =
145+ let
146+ (i ** (ipj, ei)) = oddSuccEven oj
147+ (half_ik ** eik) = evenPlusEven ei ek
148+ in
149+ (half_ik **
150+ rewrite ipj in
151+ cong {f = S} eik)
109152
110153||| Even plus Odd is Odd.
111154evenPlusOdd : Even j -> Odd k -> Odd (j + k)
112−evenPlusOdd (half_j ** pf_j) (haf_k ** pf_k) =
113− rewrite pf_j in
114− rewrite pf_k in
115− rewrite sym $ plusSuccRightSucc (half_j * 2) (haf_k * 2) in
116− rewrite sym $ multDistributesOverPlusLeft half_j haf_k 2 in
117− (half_j + haf_k ** Refl)
155+evenPlusOdd {j} {k} ej ok = rewrite plusCommutative j k in oddPlusEven ok ej
156+
157+||| Odd plus Odd is Even.
158+oddPlusOdd : Odd j -> Odd k -> Even (j + k)
159+oddPlusOdd oj ok =
160+ let
161+ (i ** (ipj, ei)) = oddSuccEven oj
162+ (haf_ik ** oik) = evenPlusOdd ei ok
163+ in
164+ (S haf_ik **
165+ rewrite ipj in
166+ rewrite oik in
167+ Refl)
118168
119169||| A helper fact.
120170multShuffle : (a, b, c : Nat) ->
@@ -129,35 +179,39 @@ multShuffle a b c =
129179||| Even times Even is Even.
130180evenMultEven : Even j -> Even k -> Even (j * k)
131181evenMultEven (half_j ** pf_j) (half_k ** pf_k) =
132− rewrite pf_j in
133− rewrite pf_k in
134− (half_j * half_k * 2 **
182+ (half_j * half_k * 2 **
183+ rewrite pf_j in
184+ rewrite pf_k in
135185 multShuffle half_j half_k 2)
136186
187+||| Odd times Even is Even.
188+oddMultEven : Odd j -> Even k -> Even (j * k)
189+oddMultEven oj (half_k ** pf_k) =
190+ let
191+ (i ** (ipj, ei)) = oddSuccEven oj
192+ (half_ik ** oik) = evenMultEven ei (half_k ** pf_k)
193+ in
194+ (half_k + half_ik **
195+ rewrite multDistributesOverPlusLeft half_k half_ik 2 in
196+ rewrite ipj in
197+ rewrite oik in
198+ rewrite pf_k in
199+ Refl)
200+
137201||| Even times Odd is Even.
138202evenMultOdd : Even j -> Odd k -> Even (j * k)
139−evenMultOdd (half_j ** pf_j) (haf_k ** pf_k) =
140− let half = half_j * haf_k * 2 in
141− rewrite pf_j in
142− rewrite pf_k in
143− rewrite multRightSuccPlus (half_j * 2) (haf_k * 2) in
144− rewrite multShuffle half_j haf_k 2 in
145− (half_j + half **
146− sym $ multDistributesOverPlusLeft half_j half 2)
203+evenMultOdd {j} {k} ej ok = rewrite multCommutative j k in oddMultEven ok ej
147204
148205||| Odd times Odd is Odd.
149206oddMultOdd : Odd j -> Odd k -> Odd (j * k)
150−oddMultOdd (haf_j ** pf_j) (haf_k ** pf_k) =
207+oddMultOdd oj (haf_k ** pf_k) =
151208 let
152− haf = haf_j * haf_k * 2
153− rem = haf_j + haf_k
209+ (i ** (ipj, ei)) = oddSuccEven oj
210+ (half_ik ** eik) = evenMultOdd ei (haf_k ** pf_k)
154211 in
155− rewrite pf_j in
156− rewrite pf_k in
157− rewrite multRightSuccPlus (haf_j * 2) (haf_k * 2) in
158− rewrite multShuffle haf_j haf_k 2 in
159− rewrite plusAssociative (haf_k * 2) (haf_j * 2) (haf * 2) in
160− rewrite sym $ multDistributesOverPlusLeft haf_k haf_j 2 in
161− rewrite plusCommutative haf_k haf_j in
162− rewrite sym $ multDistributesOverPlusLeft rem haf 2 in
163− (rem + haf ** Refl)
212+ (haf_k + half_ik **
213+ rewrite multDistributesOverPlusLeft haf_k half_ik 2 in
214+ rewrite ipj in
215+ rewrite eik in
216+ rewrite pf_k in
217+ Refl)
libs/prelude/Prelude/Nat.idr+23−43
@@ -512,19 +512,18 @@ plusLeftCancel (S left) right right' p =
512512
513513total plusRightCancel : (left : Nat) -> (left' : Nat) -> (right : Nat) ->
514514 (p : left + right = left' + right) -> left = left'
515−plusRightCancel left left' Z p = rewrite sym (plusZeroRightNeutral left) in
516− rewrite sym (plusZeroRightNeutral left') in
517− p
518−plusRightCancel left left' (S right) p =
519− plusRightCancel left left' right
520− (succInjective _ _ (rewrite plusSuccRightSucc left right in
521− rewrite plusSuccRightSucc left' right in p))
515+plusRightCancel left left' right p =
516+ plusLeftCancel right left left' $
517+ rewrite plusCommutative right left in
518+ rewrite plusCommutative right left' in
519+ p
522520
523521total plusLeftLeftRightZero : (left : Nat) -> (right : Nat) ->
524522 (p : left + right = left) -> right = Z
525−plusLeftLeftRightZero Z right p = p
526−plusLeftLeftRightZero (S left) right p =
527− plusLeftLeftRightZero left right (succInjective _ _ p)
523+plusLeftLeftRightZero left right p =
524+ plusLeftCancel left right Z $
525+ rewrite plusZeroRightNeutral left in
526+ p
528527
529528-- Mult
530529total multZeroLeftZero : (right : Nat) -> Z * right = Z
@@ -573,12 +572,11 @@ multDistributesOverPlusRight (S left) centre right =
573572
574573total multDistributesOverPlusLeft : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
575574 (left + centre) * right = (left * right) + (centre * right)
576−multDistributesOverPlusLeft Z centre right = Refl
577−multDistributesOverPlusLeft (S left) centre right =
578− let inductiveHypothesis = multDistributesOverPlusLeft left centre right in
579− rewrite inductiveHypothesis in
580− rewrite plusAssociative right (mult left right) (mult centre right) in
581− Refl
575+multDistributesOverPlusLeft left centre right =
576+ rewrite multCommutative (left + centre) right in
577+ rewrite multCommutative left right in
578+ rewrite multCommutative centre right in
579+ multDistributesOverPlusRight right left centre
582580
583581total multAssociative : (left : Nat) -> (centre : Nat) -> (right : Nat) ->
584582 left * (centre * right) = (left * centre) * right
@@ -597,11 +595,7 @@ multOneLeftNeutral (S right) =
597595 Refl
598596
599597total multOneRightNeutral : (left : Nat) -> left * 1 = left
600−multOneRightNeutral Z = Refl
601−multOneRightNeutral (S left) =
602− let inductiveHypothesis = multOneRightNeutral left in
603− rewrite inductiveHypothesis in
604− Refl
598+multOneRightNeutral left = rewrite multCommutative left 1 in multOneLeftNeutral left
605599
606600-- Minus
607601total minusSuccSucc : (left : Nat) -> (right : Nat) ->
@@ -689,10 +683,7 @@ total powerZeroOne : (base : Nat) -> power base 0 = S Z
689683powerZeroOne base = Refl
690684
691685total powerOneNeutral : (base : Nat) -> power base 1 = base
692−powerOneNeutral Z = Refl
693−powerOneNeutral (S base) =
694− let inductiveHypothesis = powerOneNeutral base in
695− rewrite inductiveHypothesis in Refl
686+powerOneNeutral base = rewrite multCommutative base 1 in multOneLeftNeutral base
696687
697688total powerOneSuccOne : (exp : Nat) -> power 1 exp = S Z
698689powerOneSuccOne Z = Refl
@@ -701,8 +692,7 @@ powerOneSuccOne (S exp) =
701692 rewrite inductiveHypothesis in Refl
702693
703694total powerSuccSuccMult : (base : Nat) -> power base 2 = mult base base
704−powerSuccSuccMult Z = Refl
705−powerSuccSuccMult (S base) = rewrite multOneRightNeutral base in Refl
695+powerSuccSuccMult base = rewrite multOneRightNeutral base in Refl
706696
707697total powerPowerMultPower : (base : Nat) -> (exp : Nat) -> (exp' : Nat) ->
708698 power (power base exp) exp' = power base (exp * exp')
@@ -796,34 +786,24 @@ minimumIdempotent Z = Refl
796786minimumIdempotent (S k) = cong (minimumIdempotent k)
797787
798788total minimumZeroZeroRight : (right : Nat) -> minimum 0 right = Z
799−minimumZeroZeroRight Z = Refl
800−minimumZeroZeroRight (S right) = minimumZeroZeroRight right
789+minimumZeroZeroRight right = Refl
801790
802791total minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
803−minimumZeroZeroLeft Z = Refl
804−minimumZeroZeroLeft (S left) = Refl
792+minimumZeroZeroLeft left = rewrite minimumCommutative left 0 in Refl
805793
806794total minimumSuccSucc : (left : Nat) -> (right : Nat) ->
807795 minimum (S left) (S right) = S (minimum left right)
808−minimumSuccSucc Z Z = Refl
809−minimumSuccSucc (S left) Z = Refl
810−minimumSuccSucc Z (S right) = Refl
811−minimumSuccSucc (S left) (S right) = Refl
796+minimumSuccSucc left right = Refl
812797
813798total maximumZeroNRight : (right : Nat) -> maximum Z right = right
814−maximumZeroNRight Z = Refl
815−maximumZeroNRight (S right) = Refl
799+maximumZeroNRight right = Refl
816800
817801total maximumZeroNLeft : (left : Nat) -> maximum left Z = left
818−maximumZeroNLeft Z = Refl
819−maximumZeroNLeft (S left) = Refl
802+maximumZeroNLeft left = rewrite maximumCommutative left Z in Refl
820803
821804total maximumSuccSucc : (left : Nat) -> (right : Nat) ->
822805 S (maximum left right) = maximum (S left) (S right)
823−maximumSuccSucc Z Z = Refl
824−maximumSuccSucc (S left) Z = Refl
825−maximumSuccSucc Z (S right) = Refl
826−maximumSuccSucc (S left) (S right) = Refl
806+maximumSuccSucc left right = Refl
827807
828808total sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
829809sucMaxL Z = Refl