37M6U67BGGKCHBINRKRCKR6QFBZQH7JAB6ZDYBAOQ7Q3XMFM5GWAC 3WLOPTAUKTLZP3B3DY6J7AKA4AKYGW34MGZRLWCKKR2Q6GUQTUPQC 53I57WPJKAX7YSCLT6HM6PS6T2DHIO5Y4NFULRXWI5ZRG5UPMODQC QJMKKLU2UF45IRLVJHSQQ6PHTLHHX34Z4ROJGQLBRQTMQ54D6G5AC CO3C7GSZ2X62ALXW2EAWDHCRSXCNVKIIHCL47GYZ32OHZER4NLZQC XNPLRKJ4ZK442XNJ5BC7TO3DKXGXFSOSGBZBPW5HZZDHY3IVD6FAC K7TT3LDM6HYYXLSYFSJZRQZ6GOGTDJ7F5KFU7GBPJOKN2DHJLHMQC XJZ5YZW6TIBBMPL2TGEA2ERD2UYZ4PIXNSV25ETLUVPLDM3RA5EQC 4L2YWRMCKZ56NCRC44XVDZQ5BEKHX26C4GQZ5TIL35Y33VKFTBCQC K6VKF3FC5BN3ODMH5GNGUTYN6NSNIUXYYOBMYKG2BMGXJOEKOH5AC ZADJ47JPO7SQJNR5OMSJSYPUGDVBVHGBXZBEKTA7FEK7F5437MSAC OQYT367KXCQGIZPWQXNFQB627WJGYD6T5WF4KBBXQKHN2SXL554QC LDJ4DDJZJV3W2UZIK6USOW5IADAWHDYM3EMZNCBFDKCXFYVS3WCAC XGXJVBQB7LVLGIHMQYZRP53X7XBKDXFM4TFWDF3ZFZRPMCYPF4IAC RUIGRXTKM6BQ532W7KU3RKDXMRNRGDVGMA2ODMX2D2F3PCLF3GAQC WJJ6PMS6GYR5NIQI6Q6YH6WQSTJ3U56F3KZJOSYHTRAZ5MKIPXAAC TTGQ6KKFCCLVNZDOWWBOOXKEKMCELYB5ULXLXWY4THZMZCUASGWQC BLJHEFB7SWAE4XB3GUAWA6TOVFKONOZO7URKJVSUNXGRXLKZHXOQC import Builtinimport Algebra.Group.Magmaimport Algebra.Group.Semigroupimport Algebra.Group.Monoidimport Algebra.Relation.Equivalenceimport Algebra.Relation.Preorderimport Algebra.Relation.Orderimport Algebra.Ring.Semiringimport public Control.Showimport public Data.PrimInteger%default totalpublic exportdata Natural = Zero | Succesor Natural%builtin Natural Natural---- Restrictions--public exportdata NotZero : Natural -> Type whereIsNotZero : NotZero (Succesor _)public exportUninhabited (NotZero Zero) whereuninhabited IsNotZero impossible---- Equivalence--data NaturalEquiv : (x, y : Natural) -> Type whereBothZero : NaturalEquiv Zero ZeroSuccesorEquiv : NaturalEquiv x y -> NaturalEquiv (Succesor x) (Succesor y)public exportUninhabited (NaturalEquiv Zero (Succesor y)) whereuninhabited BothZero impossibleuninhabited (SuccesorEquiv _) impossiblepublic exportUninhabited (NaturalEquiv (Succesor y) Zero) whereuninhabited BothZero impossibleuninhabited (SuccesorEquiv _) impossibleexportproofNotEquivThenNotSuccesorEquiv : {x, y : Natural}-> Not (NaturalEquiv x y)-> Not (NaturalEquiv (Succesor x) (Succesor y))proofNotEquivThenNotSuccesorEquiv h (SuccesorEquiv ctra) = h ctrapublic exportEquivalence Natural whereEquiv = NaturalEquivdecEquiv Zero Zero = Yes BothZerodecEquiv Zero (Succesor _) = No absurddecEquiv (Succesor _) Zero = No absurddecEquiv (Succesor x) (Succesor y) =case decEquiv x y ofYes p => Yes $ SuccesorEquiv pNo cp => No $ proofNotEquivThenNotSuccesorEquiv cp---- Order--data NaturalLTE : (x, y : Natural) -> Type whereZeroLTEAny : NaturalLTE Zero ySuccesorLTE : NaturalLTE x y -> NaturalLTE (Succesor x) (Succesor y)public exportUninhabited (NaturalLTE (Succesor y) Zero) whereuninhabited ZeroLTEAny impossibleuninhabited (SuccesorLTE _) impossibleexportproofLTEThenLTESuccesor : NaturalLTE x y -> NaturalLTE x (Succesor y)proofLTEThenLTESuccesor ZeroLTEAny = ZeroLTEAnyproofLTEThenLTESuccesor (SuccesorLTE p) = SuccesorLTE $ proofLTEThenLTESuccesor pexportproofNotLTEThenNotSuccesorLTE : Not (NaturalLTE x y) -> Not (NaturalLTE (Succesor x) (Succesor y))proofNotLTEThenNotSuccesorLTE h (SuccesorLTE ctra) = h ctrapublic exportPreorder Natural whereLTE = NaturalLTE
decLTE Zero y = Yes ZeroLTEAnydecLTE (Succesor _) Zero = No absurddecLTE (Succesor x) (Succesor y) =case decLTE x y ofYes p => Yes $ SuccesorLTE pNo cp => No $ proofNotLTEThenNotSuccesorLTE cp
import public Data.Natural.Basicimport public Data.Natural.ExtraOperations
proofTransitivity Zero Zero _ ZeroLTEAny ZeroLTEAny = ZeroLTEAnyproofTransitivity Zero (Succesor _) (Succesor _) ZeroLTEAny (SuccesorLTE _) = ZeroLTEAnyproofTransitivity (Succesor x) (Succesor y) (Succesor z) (SuccesorLTE p1) (SuccesorLTE p2) =SuccesorLTE $ proofTransitivity x y z p1 p2
import public Data.Natural.Groupimport public Data.Natural.Semiring
public exportOrder Natural whereLT x = NaturalLTE (Succesor x)decLT Zero Zero = No absurddecLT Zero (Succesor _) = Yes $ SuccesorLTE ZeroLTEAnydecLT (Succesor _) Zero = No absurddecLT (Succesor x) (Succesor y) =case decLT x y ofYes p => Yes $ SuccesorLTE pNo cp => No $ proofNotLTEThenNotSuccesorLTE cpproofAntisymetry Zero Zero ZeroLTEAny ZeroLTEAny = BothZeroproofAntisymetry (Succesor x) (Succesor y) (SuccesorLTE p1) (SuccesorLTE p2) =SuccesorEquiv $ proofAntisymetry x y p1 p2proofLTThenLTE (SuccesorLTE p) = proofLTEThenLTESuccesor pproofLTEThenLTOrEquiv Zero Zero ZeroLTEAny = Right BothZeroproofLTEThenLTOrEquiv Zero (Succesor _) ZeroLTEAny = Left $ SuccesorLTE ZeroLTEAnyproofLTEThenLTOrEquiv (Succesor x) (Succesor y) (SuccesorLTE p) =case proofLTEThenLTOrEquiv x y p ofLeft l => Left $ SuccesorLTE lRight e => Right $ SuccesorEquiv e---- FromInteger--natFromPrimInteger : (x : Integer) -> {auto ok : x `GTE` 0} -> NaturalnatFromPrimInteger 0 = ZeronatFromPrimInteger x = case (decGTE (prim__sub_Integer x 1) 0) ofYes p => Succesor $ assert_total $ natFromPrimInteger $ prim__sub_Integer x 1No cp => void $ believe_me () -- TODO: impossible%builtin IntegerToNatural natFromPrimIntegernatToPrimInteger : Natural -> IntegernatToPrimInteger Zero = 0natToPrimInteger (Succesor x) = prim__add_Integer 1 $ natToPrimInteger x%builtin NaturalToInteger natToPrimIntegerpublic exportSupportPrimIntegerLiteral Natural wherePrimIntegerRestriction x = x `GTE` 0fromPrimInteger = natFromPrimIntegertoPrimInteger = natToPrimIntegerpublic exportShow Natural whereshow = show . toPrimInteger---- Operations--public exportplus : (x, y : Natural) -> Naturalplus x Zero = xplus x (Succesor y) = Succesor $ plus x yexportproofPlusLeftIdentity : (x : Natural) -> plus Zero x = xproofPlusLeftIdentity Zero = ReflproofPlusLeftIdentity (Succesor x) = rewrite proofPlusLeftIdentity x in ReflexportproofPlusLeftReduction : (x, y : Natural)-> plus (Succesor x) y = Succesor (plus x y)proofPlusLeftReduction x Zero = ReflproofPlusLeftReduction x (Succesor y) =rewrite proofPlusLeftReduction x y in ReflexportproofPlusCommutative : (x, y : Natural) -> plus x y = plus y xproofPlusCommutative x Zero = rewrite proofPlusLeftIdentity x in ReflproofPlusCommutative x (Succesor y) =rewrite proofPlusCommutative x y inrewrite proofPlusLeftReduction y x inReflexportproofPlusAssociative : (x, y, z : Natural)-> plus x (plus y z) = plus (plus x y) zproofPlusAssociative _ _ Zero = ReflproofPlusAssociative x y (Succesor z) =rewrite proofPlusAssociative x y z in Reflpublic export[NaturalSumMagma] Magma Natural where(<>) = pluspublic export[NaturalSumCommutativeMagma] CommutativeMagma Natural using NaturalSumMagma whereproofCommutative = proofPlusCommutativepublic export[NaturalSumSemigroup] Semigroup Natural using NaturalSumMagma whereproofAssociative = proofPlusAssociativepublic export[NaturalSumCommutativeSemigroup] CommutativeSemigroup Natural using NaturalSumCommutativeMagma NaturalSumSemigroup wherepublic export[NaturalSumMonoid] Monoid Natural using NaturalSumSemigroup whereid = ZeroproofLeftIdentity = proofPlusLeftIdentityproofRightIdentity _ = Reflpublic export[NaturalSumCommutativeMonoid] CommutativeMonoid Natural using NaturalSumCommutativeSemigroup NaturalSumMonoid wherepublic exportminus : (x, y : Natural) -> {auto ok : x `GTE` y} -> Naturalminus x Zero = xminus (Succesor x) (Succesor y) {ok=(SuccesorLTE p)} = minus x ypublic exportmult : (x, y : Natural) -> Naturalmult _ Zero = Zeromult x (Succesor y) = x `plus` mult x yexportproofMultLeftIdentity : (x : Natural) -> mult (Succesor Zero) x = xproofMultLeftIdentity Zero = ReflproofMultLeftIdentity (Succesor x) =rewrite proofMultLeftIdentity x inrewrite proofPlusLeftReduction Zero x inrewrite proofPlusLeftIdentity x inReflexportproofMultLeftAnnihilation : (x : Natural) -> mult Zero x = ZeroproofMultLeftAnnihilation Zero = ReflproofMultLeftAnnihilation (Succesor x) =rewrite proofMultLeftAnnihilation x in ReflexportproofMultRightAnnihilation : (x : Natural) -> mult x Zero = ZeroproofMultRightAnnihilation Zero = ReflproofMultRightAnnihilation (Succesor x) =rewrite proofMultRightAnnihilation x in ReflexportproofMultCommutative : (x, y : Natural) -> mult x y = mult y xproofMultCommutative Zero Zero = ReflproofMultCommutative Zero (Succesor y) =rewrite proofMultCommutative Zero y in ReflproofMultCommutative (Succesor x) Zero =rewrite proofMultCommutative Zero x in ReflproofMultCommutative (Succesor x) (Succesor y) =rewrite proofPlusLeftReduction x (mult (Succesor x) y) inrewrite proofPlusLeftReduction y (mult (Succesor y) x) inrewrite proofMultCommutative (Succesor x) y inrewrite proofMultCommutative (Succesor y) x inrewrite proofMultCommutative x y inrewrite proofPlusAssociative x y (mult y x) inrewrite proofPlusAssociative y x (mult y x) inrewrite proofPlusCommutative x y inReflexportproofMultLeftReduction : (x, y : Natural)-> mult (Succesor x) y = plus y (mult x y)proofMultLeftReduction x y =rewrite proofMultCommutative (Succesor x) y inrewrite proofMultCommutative x y inReflexportproofMultLeftDistributesPlus : (x, y, z : Natural)-> mult x (plus y z) = plus (mult x y) (mult x z)proofMultLeftDistributesPlus Zero y z =rewrite proofMultLeftAnnihilation y inrewrite proofMultLeftAnnihilation z inrewrite proofMultLeftAnnihilation (plus y z) inReflproofMultLeftDistributesPlus (Succesor x) y z =rewrite proofMultLeftReduction x y inrewrite proofMultLeftReduction x z inrewrite proofMultLeftReduction x (plus y z) inrewrite proofMultLeftDistributesPlus x y z inrewrite proofPlusAssociative (plus y (mult x y)) z (mult x z) inrewrite proofPlusCommutative (plus y (mult x y)) z inrewrite proofPlusAssociative z y (mult x y) inrewrite proofPlusCommutative z y inrewrite proofPlusAssociative (plus y z) (mult x y) (mult x z) inReflproofMultRightDistributesPlus : (x, y, z : Natural)-> mult (plus x y) z = plus (mult x z) (mult y z)proofMultRightDistributesPlus x y z =rewrite proofMultCommutative (plus x y) z inrewrite proofMultLeftDistributesPlus z x y inrewrite proofMultCommutative z x inrewrite proofMultCommutative z y inReflpublic export[NaturalMultMagma] Magma Natural where(<>) = multpublic export[NaturalMultSemigroup] Semigroup Natural using NaturalMultMagma whereproofAssociative x y Zero = ReflproofAssociative x y (Succesor z) =rewrite proofMultLeftDistributesPlus x y (mult y z) inrewrite proofAssociative x y z inReflpublic export[NaturalMultMonoid] Monoid Natural using NaturalMultSemigroup whereid = Succesor ZeroproofLeftIdentity = proofMultLeftIdentityproofRightIdentity _ = Reflpublic exportdivRem : (x, y : Natural) -> {auto ok : NotZero y} -> (Natural, Natural)divRem x y = case decLTE y x ofYes _ => let (d, r) := divRem (x `minus` y) y in (Succesor d, r)No _ => (Zero, x)public exportdiv : (x, y : Natural) -> {auto ok : NotZero y} -> Naturaldiv x y = fst $ divRem x ypublic exportrem : (x, y : Natural) -> {auto ok : NotZero y} -> Naturalrem x y = snd $ divRem x ypublic exportSemiring Natural where(+) = plus(*) = multzero = 0one = 1proofSumZero = proofRightIdentity @{NaturalSumMonoid}proofSumCommutative = proofCommutative @{NaturalSumCommutativeMagma}proofSumAssociative = proofAssociative @{NaturalSumSemigroup}proofMultOneLeft = proofLeftIdentity @{NaturalMultMonoid}proofMultOneRight = proofRightIdentity @{NaturalMultMonoid}proofMultAssociative = proofAssociative @{NaturalMultSemigroup}proofMultDistributesSumLeft = proofMultLeftDistributesPlusproofMultDistributesSumRight = proofMultRightDistributesPluszeroAnnihilatorLeft = proofMultLeftAnnihilationzeroAnnihilatorRight = proofMultRightAnnihilation
import public Data.Natural.SupportPrimIntegerLiteralimport public Data.Natural.Show
module Data.Natural.SupportPrimIntegerLiteralimport Builtinimport Algebra.Relation.Preorderimport Data.PrimIntegerimport public Data.Natural.Basic%default totalpublic exportnatFromPrimInteger : (x : Integer) -> {auto ok : x `GTE` 0} -> NaturalnatFromPrimInteger 0 = ZeronatFromPrimInteger x = case (decGTE (prim__sub_Integer x 1) 0) ofYes p => Succesor $ assert_total $ natFromPrimInteger $ prim__sub_Integer x 1No cp => void $ believe_me () -- TODO: impossible-- TODO: Compiler not happy-- %builtin IntegerToNatural natFromPrimIntegerpublic exportnatToPrimInteger : Natural -> IntegernatToPrimInteger Zero = 0natToPrimInteger (Succesor x) = prim__add_Integer 1 $ natToPrimInteger x-- TODO: Compiler not happy-- %builtin NaturalToInteger natToPrimIntegerpublic exportSupportPrimIntegerLiteral Natural wherePrimIntegerRestriction x = x `GTE` 0fromPrimInteger = natFromPrimIntegertoPrimInteger = natToPrimInteger
module Data.Natural.Showimport Builtinimport Control.Showimport Data.PrimIntegerimport public Data.Natural.SupportPrimIntegerLiteralpublic exportShow Natural whereshow = show . toPrimInteger
module Data.Natural.Semiringimport Builtinimport Algebra.Group.Magmaimport Algebra.Group.Semigroupimport Algebra.Group.Monoidimport Algebra.Ring.Semiringimport public Data.Natural.Basicimport public Data.Natural.Group%default totalpublic exportSemiring Natural where(+) = add(*) = multzero = Zeroone = (Succesor Zero)proofSumZero = proofRightIdentity @{NaturalSumMonoid}proofSumCommutative = proofCommutative @{NaturalSumCommutativeMagma}proofSumAssociative = proofAssociative @{NaturalSumSemigroup}proofMultOneLeft = proofLeftIdentity @{NaturalMultMonoid}proofMultOneRight = proofRightIdentity @{NaturalMultMonoid}proofMultAssociative = proofAssociative @{NaturalMultSemigroup}proofMultDistributesSumLeft = proofMultLeftDistributesAddproofMultDistributesSumRight = proofMultRightDistributesAddzeroAnnihilatorLeft = proofMultLeftAnnihilationzeroAnnihilatorRight = proofMultRightAnnihilation
module Data.Natural.Orderimport Builtinimport Algebra.Relation.Equivalenceimport Algebra.Relation.Preorderimport Algebra.Relation.Orderimport public Data.Natural.Basicimport public Data.Natural.Equivalence%default totalpublic exportdata NaturalLTE : (x, y : Natural) -> Type whereZeroLTEAny : NaturalLTE Zero ySuccesorLTE : NaturalLTE x y -> NaturalLTE (Succesor x) (Succesor y)public exportUninhabited (NaturalLTE (Succesor y) Zero) whereuninhabited ZeroLTEAny impossibleuninhabited (SuccesorLTE _) impossibleexportproofLTEThenLTESuccesor : NaturalLTE x y -> NaturalLTE x (Succesor y)proofLTEThenLTESuccesor ZeroLTEAny = ZeroLTEAnyproofLTEThenLTESuccesor (SuccesorLTE p) = SuccesorLTE $ proofLTEThenLTESuccesor pexportproofNotLTEThenNotSuccesorLTE : Not (NaturalLTE x y) -> Not (NaturalLTE (Succesor x) (Succesor y))proofNotLTEThenNotSuccesorLTE h (SuccesorLTE ctra) = h ctrapublic exportPreorder Natural whereLTE = NaturalLTEdecLTE Zero y = Yes ZeroLTEAnydecLTE (Succesor _) Zero = No absurddecLTE (Succesor x) (Succesor y) =case decLTE x y ofYes p => Yes $ SuccesorLTE pNo cp => No $ proofNotLTEThenNotSuccesorLTE cpproofReflexivity Zero = ZeroLTEAnyproofReflexivity (Succesor x) = SuccesorLTE $ proofReflexivity xproofTransitivity Zero Zero _ ZeroLTEAny ZeroLTEAny = ZeroLTEAnyproofTransitivity Zero (Succesor _) (Succesor _) ZeroLTEAny (SuccesorLTE _) = ZeroLTEAnyproofTransitivity (Succesor x) (Succesor y) (Succesor z) (SuccesorLTE p1) (SuccesorLTE p2) =SuccesorLTE $ proofTransitivity x y z p1 p2public exportOrder Natural whereLT x = NaturalLTE (Succesor x)decLT Zero Zero = No absurddecLT Zero (Succesor _) = Yes $ SuccesorLTE ZeroLTEAnydecLT (Succesor _) Zero = No absurddecLT (Succesor x) (Succesor y) =case decLT x y ofYes p => Yes $ SuccesorLTE pNo cp => No $ proofNotLTEThenNotSuccesorLTE cpproofAntisymetry Zero Zero ZeroLTEAny ZeroLTEAny = BothZeroproofAntisymetry (Succesor x) (Succesor y) (SuccesorLTE p1) (SuccesorLTE p2) =SuccesorEquiv $ proofAntisymetry x y p1 p2proofLTThenLTE (SuccesorLTE p) = proofLTEThenLTESuccesor pproofLTEThenLTOrEquiv Zero Zero ZeroLTEAny = Right BothZeroproofLTEThenLTOrEquiv Zero (Succesor _) ZeroLTEAny = Left $ SuccesorLTE ZeroLTEAnyproofLTEThenLTOrEquiv (Succesor x) (Succesor y) (SuccesorLTE p) =case proofLTEThenLTOrEquiv x y p ofLeft l => Left $ SuccesorLTE lRight e => Right $ SuccesorEquiv e
module Data.Natural.Groupimport Builtinimport Algebra.Group.Magmaimport Algebra.Group.Semigroupimport Algebra.Group.Monoidimport public Data.Natural.Basicpublic export[NaturalSumMagma] Magma Natural where(<>) = addpublic export[NaturalSumCommutativeMagma] CommutativeMagma Natural using NaturalSumMagma whereproofCommutative = proofAddCommutativepublic export[NaturalSumSemigroup] Semigroup Natural using NaturalSumMagma whereproofAssociative = proofAddAssociativepublic export[NaturalSumCommutativeSemigroup] CommutativeSemigroup Natural using NaturalSumCommutativeMagma NaturalSumSemigroup wherepublic export[NaturalSumMonoid] Monoid Natural using NaturalSumSemigroup whereid = ZeroproofLeftIdentity = proofAddLeftIdentityproofRightIdentity _ = Reflpublic export[NaturalSumCommutativeMonoid] CommutativeMonoid Natural using NaturalSumCommutativeSemigroup NaturalSumMonoid wherepublic export[NaturalMultMagma] Magma Natural where(<>) = multpublic export[NaturalMultSemigroup] Semigroup Natural using NaturalMultMagma whereproofAssociative x y Zero = ReflproofAssociative x y (Succesor z) =rewrite proofMultLeftDistributesAdd x y (mult y z) inrewrite proofAssociative x y z inReflpublic export[NaturalMultMonoid] Monoid Natural using NaturalMultSemigroup whereid = Succesor ZeroproofLeftIdentity = proofMultLeftIdentityproofRightIdentity _ = Refl
module Data.Natural.ExtraOperationsimport Builtinimport Algebra.Relation.Preorderimport public Data.Natural.Basicimport public Data.Natural.Order%default totalpublic exportminus : (x, y : Natural) -> {auto ok : x `GTE` y} -> Naturalminus x Zero = xminus (Succesor x) (Succesor y) {ok=(SuccesorLTE p)} = minus x ypublic exportdivRem : (x, y : Natural) -> {auto ok : NotZero y} -> (Natural, Natural)divRem x y = case decLTE y x ofYes _ => let (d, r) := divRem (x `minus` y) y in (Succesor d, r)No _ => (Zero, x)public exportdiv : (x, y : Natural) -> {auto ok : NotZero y} -> Naturaldiv x y = fst $ divRem x ypublic exportrem : (x, y : Natural) -> {auto ok : NotZero y} -> Naturalrem x y = snd $ divRem x y
module Data.Natural.Equivalenceimport Builtinimport Algebra.Relation.Equivalenceimport public Data.Natural.Basicpublic exportdata NaturalEquiv : (x, y : Natural) -> Type whereBothZero : NaturalEquiv Zero ZeroSuccesorEquiv : NaturalEquiv x y -> NaturalEquiv (Succesor x) (Succesor y)public exportUninhabited (NaturalEquiv Zero (Succesor y)) whereuninhabited BothZero impossibleuninhabited (SuccesorEquiv _) impossiblepublic exportUninhabited (NaturalEquiv (Succesor y) Zero) whereuninhabited BothZero impossibleuninhabited (SuccesorEquiv _) impossibleexportproofNotEquivThenNotSuccesorEquiv : {x, y : Natural}-> Not (NaturalEquiv x y)-> Not (NaturalEquiv (Succesor x) (Succesor y))proofNotEquivThenNotSuccesorEquiv h (SuccesorEquiv ctra) = h ctrapublic exportEquivalence Natural whereEquiv = NaturalEquivdecEquiv Zero Zero = Yes BothZerodecEquiv Zero (Succesor _) = No absurddecEquiv (Succesor _) Zero = No absurddecEquiv (Succesor x) (Succesor y) =case decEquiv x y ofYes p => Yes $ SuccesorEquiv pNo cp => No $ proofNotEquivThenNotSuccesorEquiv cp
module Data.Natural.Basicimport Builtin%default totalpublic exportdata Natural = Zero | Succesor Natural%builtin Natural Natural---- Restrictions--public exportdata NotZero : Natural -> Type whereIsNotZero : NotZero (Succesor _)public exportUninhabited (NotZero Zero) whereuninhabited IsNotZero impossible---- Operations---- Additionpublic exportadd : (x, y : Natural) -> Naturaladd x Zero = xadd x (Succesor y) = Succesor $ add x yexportproofAddLeftIdentity : (x : Natural) -> add Zero x = xproofAddLeftIdentity Zero = ReflproofAddLeftIdentity (Succesor x) = rewrite proofAddLeftIdentity x in ReflexportproofAddLeftReduction : (x, y : Natural)-> add (Succesor x) y = Succesor (add x y)proofAddLeftReduction x Zero = ReflproofAddLeftReduction x (Succesor y) =rewrite proofAddLeftReduction x y in ReflexportproofAddCommutative : (x, y : Natural) -> add x y = add y xproofAddCommutative x Zero = rewrite proofAddLeftIdentity x in ReflproofAddCommutative x (Succesor y) =rewrite proofAddCommutative x y inrewrite proofAddLeftReduction y x inReflexportproofAddAssociative : (x, y, z : Natural)-> add x (add y z) = add (add x y) zproofAddAssociative _ _ Zero = ReflproofAddAssociative x y (Succesor z) =rewrite proofAddAssociative x y z in Refl-- Diffpublic exportdiff : (x, y : Natural) -> Naturaldiff Zero y = ydiff x Zero = xdiff (Succesor x) (Succesor y) = diff x y-- Multpublic exportmult : (x, y : Natural) -> Naturalmult _ Zero = Zeromult x (Succesor y) = x `add` mult x yexportproofMultLeftIdentity : (x : Natural) -> mult (Succesor Zero) x = xproofMultLeftIdentity Zero = ReflproofMultLeftIdentity (Succesor x) =rewrite proofMultLeftIdentity x inrewrite proofAddLeftReduction Zero x inrewrite proofAddLeftIdentity x inReflexportproofMultLeftAnnihilation : (x : Natural) -> mult Zero x = ZeroproofMultLeftAnnihilation Zero = ReflproofMultLeftAnnihilation (Succesor x) =rewrite proofMultLeftAnnihilation x in ReflexportproofMultRightAnnihilation : (x : Natural) -> mult x Zero = ZeroproofMultRightAnnihilation Zero = ReflproofMultRightAnnihilation (Succesor x) =rewrite proofMultRightAnnihilation x in ReflexportproofMultCommutative : (x, y : Natural) -> mult x y = mult y xproofMultCommutative Zero Zero = ReflproofMultCommutative Zero (Succesor y) =rewrite proofMultCommutative Zero y in ReflproofMultCommutative (Succesor x) Zero =rewrite proofMultCommutative Zero x in ReflproofMultCommutative (Succesor x) (Succesor y) =rewrite proofAddLeftReduction x (mult (Succesor x) y) inrewrite proofAddLeftReduction y (mult (Succesor y) x) inrewrite proofMultCommutative (Succesor x) y inrewrite proofMultCommutative (Succesor y) x inrewrite proofMultCommutative x y inrewrite proofAddAssociative x y (mult y x) inrewrite proofAddAssociative y x (mult y x) inrewrite proofAddCommutative x y inReflexportproofMultLeftReduction : (x, y : Natural)-> mult (Succesor x) y = add y (mult x y)proofMultLeftReduction x y =rewrite proofMultCommutative (Succesor x) y inrewrite proofMultCommutative x y inReflexportproofMultLeftDistributesAdd : (x, y, z : Natural)-> mult x (add y z) = add (mult x y) (mult x z)proofMultLeftDistributesAdd Zero y z =rewrite proofMultLeftAnnihilation y inrewrite proofMultLeftAnnihilation z inrewrite proofMultLeftAnnihilation (add y z) inReflproofMultLeftDistributesAdd (Succesor x) y z =rewrite proofMultLeftReduction x y inrewrite proofMultLeftReduction x z inrewrite proofMultLeftReduction x (add y z) inrewrite proofMultLeftDistributesAdd x y z inrewrite proofAddAssociative (add y (mult x y)) z (mult x z) inrewrite proofAddCommutative (add y (mult x y)) z inrewrite proofAddAssociative z y (mult x y) inrewrite proofAddCommutative z y inrewrite proofAddAssociative (add y z) (mult x y) (mult x z) inReflexportproofMultRightDistributesAdd : (x, y, z : Natural)-> mult (add x y) z = add (mult x z) (mult y z)proofMultRightDistributesAdd x y z =rewrite proofMultCommutative (add x y) z inrewrite proofMultLeftDistributesAdd z x y inrewrite proofMultCommutative z x inrewrite proofMultCommutative z y inRefl