37M6U67BGGKCHBINRKRCKR6QFBZQH7JAB6ZDYBAOQ7Q3XMFM5GWAC
3WLOPTAUKTLZP3B3DY6J7AKA4AKYGW34MGZRLWCKKR2Q6GUQTUPQC
53I57WPJKAX7YSCLT6HM6PS6T2DHIO5Y4NFULRXWI5ZRG5UPMODQC
QJMKKLU2UF45IRLVJHSQQ6PHTLHHX34Z4ROJGQLBRQTMQ54D6G5AC
CO3C7GSZ2X62ALXW2EAWDHCRSXCNVKIIHCL47GYZ32OHZER4NLZQC
XNPLRKJ4ZK442XNJ5BC7TO3DKXGXFSOSGBZBPW5HZZDHY3IVD6FAC
K7TT3LDM6HYYXLSYFSJZRQZ6GOGTDJ7F5KFU7GBPJOKN2DHJLHMQC
XJZ5YZW6TIBBMPL2TGEA2ERD2UYZ4PIXNSV25ETLUVPLDM3RA5EQC
4L2YWRMCKZ56NCRC44XVDZQ5BEKHX26C4GQZ5TIL35Y33VKFTBCQC
K6VKF3FC5BN3ODMH5GNGUTYN6NSNIUXYYOBMYKG2BMGXJOEKOH5AC
ZADJ47JPO7SQJNR5OMSJSYPUGDVBVHGBXZBEKTA7FEK7F5437MSAC
OQYT367KXCQGIZPWQXNFQB627WJGYD6T5WF4KBBXQKHN2SXL554QC
LDJ4DDJZJV3W2UZIK6USOW5IADAWHDYM3EMZNCBFDKCXFYVS3WCAC
XGXJVBQB7LVLGIHMQYZRP53X7XBKDXFM4TFWDF3ZFZRPMCYPF4IAC
RUIGRXTKM6BQ532W7KU3RKDXMRNRGDVGMA2ODMX2D2F3PCLF3GAQC
WJJ6PMS6GYR5NIQI6Q6YH6WQSTJ3U56F3KZJOSYHTRAZ5MKIPXAAC
TTGQ6KKFCCLVNZDOWWBOOXKEKMCELYB5ULXLXWY4THZMZCUASGWQC
BLJHEFB7SWAE4XB3GUAWA6TOVFKONOZO7URKJVSUNXGRXLKZHXOQC
import Builtin
import Algebra.Group.Magma
import Algebra.Group.Semigroup
import Algebra.Group.Monoid
import Algebra.Relation.Equivalence
import Algebra.Relation.Preorder
import Algebra.Relation.Order
import Algebra.Ring.Semiring
import public Control.Show
import public Data.PrimInteger
%default total
public export
data Natural = Zero | Succesor Natural
%builtin Natural Natural
--
-- Restrictions
--
public export
data NotZero : Natural -> Type where
IsNotZero : NotZero (Succesor _)
public export
Uninhabited (NotZero Zero) where
uninhabited IsNotZero impossible
--
-- Equivalence
--
data NaturalEquiv : (x, y : Natural) -> Type where
BothZero : NaturalEquiv Zero Zero
SuccesorEquiv : NaturalEquiv x y -> NaturalEquiv (Succesor x) (Succesor y)
public export
Uninhabited (NaturalEquiv Zero (Succesor y)) where
uninhabited BothZero impossible
uninhabited (SuccesorEquiv _) impossible
public export
Uninhabited (NaturalEquiv (Succesor y) Zero) where
uninhabited BothZero impossible
uninhabited (SuccesorEquiv _) impossible
export
proofNotEquivThenNotSuccesorEquiv : {x, y : Natural}
-> Not (NaturalEquiv x y)
-> Not (NaturalEquiv (Succesor x) (Succesor y))
proofNotEquivThenNotSuccesorEquiv h (SuccesorEquiv ctra) = h ctra
public export
Equivalence Natural where
Equiv = NaturalEquiv
decEquiv Zero Zero = Yes BothZero
decEquiv Zero (Succesor _) = No absurd
decEquiv (Succesor _) Zero = No absurd
decEquiv (Succesor x) (Succesor y) =
case decEquiv x y of
Yes p => Yes $ SuccesorEquiv p
No cp => No $ proofNotEquivThenNotSuccesorEquiv cp
--
-- Order
--
data NaturalLTE : (x, y : Natural) -> Type where
ZeroLTEAny : NaturalLTE Zero y
SuccesorLTE : NaturalLTE x y -> NaturalLTE (Succesor x) (Succesor y)
public export
Uninhabited (NaturalLTE (Succesor y) Zero) where
uninhabited ZeroLTEAny impossible
uninhabited (SuccesorLTE _) impossible
export
proofLTEThenLTESuccesor : NaturalLTE x y -> NaturalLTE x (Succesor y)
proofLTEThenLTESuccesor ZeroLTEAny = ZeroLTEAny
proofLTEThenLTESuccesor (SuccesorLTE p) = SuccesorLTE $ proofLTEThenLTESuccesor p
export
proofNotLTEThenNotSuccesorLTE : Not (NaturalLTE x y) -> Not (NaturalLTE (Succesor x) (Succesor y))
proofNotLTEThenNotSuccesorLTE h (SuccesorLTE ctra) = h ctra
public export
Preorder Natural where
LTE = NaturalLTE
decLTE Zero y = Yes ZeroLTEAny
decLTE (Succesor _) Zero = No absurd
decLTE (Succesor x) (Succesor y) =
case decLTE x y of
Yes p => Yes $ SuccesorLTE p
No cp => No $ proofNotLTEThenNotSuccesorLTE cp
import public Data.Natural.Basic
import public Data.Natural.ExtraOperations
proofTransitivity Zero Zero _ ZeroLTEAny ZeroLTEAny = ZeroLTEAny
proofTransitivity Zero (Succesor _) (Succesor _) ZeroLTEAny (SuccesorLTE _) = ZeroLTEAny
proofTransitivity (Succesor x) (Succesor y) (Succesor z) (SuccesorLTE p1) (SuccesorLTE p2) =
SuccesorLTE $ proofTransitivity x y z p1 p2
import public Data.Natural.Group
import public Data.Natural.Semiring
public export
Order Natural where
LT x = NaturalLTE (Succesor x)
decLT Zero Zero = No absurd
decLT Zero (Succesor _) = Yes $ SuccesorLTE ZeroLTEAny
decLT (Succesor _) Zero = No absurd
decLT (Succesor x) (Succesor y) =
case decLT x y of
Yes p => Yes $ SuccesorLTE p
No cp => No $ proofNotLTEThenNotSuccesorLTE cp
proofAntisymetry Zero Zero ZeroLTEAny ZeroLTEAny = BothZero
proofAntisymetry (Succesor x) (Succesor y) (SuccesorLTE p1) (SuccesorLTE p2) =
SuccesorEquiv $ proofAntisymetry x y p1 p2
proofLTThenLTE (SuccesorLTE p) = proofLTEThenLTESuccesor p
proofLTEThenLTOrEquiv Zero Zero ZeroLTEAny = Right BothZero
proofLTEThenLTOrEquiv Zero (Succesor _) ZeroLTEAny = Left $ SuccesorLTE ZeroLTEAny
proofLTEThenLTOrEquiv (Succesor x) (Succesor y) (SuccesorLTE p) =
case proofLTEThenLTOrEquiv x y p of
Left l => Left $ SuccesorLTE l
Right e => Right $ SuccesorEquiv e
--
-- FromInteger
--
natFromPrimInteger : (x : Integer) -> {auto ok : x `GTE` 0} -> Natural
natFromPrimInteger 0 = Zero
natFromPrimInteger x = case (decGTE (prim__sub_Integer x 1) 0) of
Yes p => Succesor $ assert_total $ natFromPrimInteger $ prim__sub_Integer x 1
No cp => void $ believe_me () -- TODO: impossible
%builtin IntegerToNatural natFromPrimInteger
natToPrimInteger : Natural -> Integer
natToPrimInteger Zero = 0
natToPrimInteger (Succesor x) = prim__add_Integer 1 $ natToPrimInteger x
%builtin NaturalToInteger natToPrimInteger
public export
SupportPrimIntegerLiteral Natural where
PrimIntegerRestriction x = x `GTE` 0
fromPrimInteger = natFromPrimInteger
toPrimInteger = natToPrimInteger
public export
Show Natural where
show = show . toPrimInteger
--
-- Operations
--
public export
plus : (x, y : Natural) -> Natural
plus x Zero = x
plus x (Succesor y) = Succesor $ plus x y
export
proofPlusLeftIdentity : (x : Natural) -> plus Zero x = x
proofPlusLeftIdentity Zero = Refl
proofPlusLeftIdentity (Succesor x) = rewrite proofPlusLeftIdentity x in Refl
export
proofPlusLeftReduction : (x, y : Natural)
-> plus (Succesor x) y = Succesor (plus x y)
proofPlusLeftReduction x Zero = Refl
proofPlusLeftReduction x (Succesor y) =
rewrite proofPlusLeftReduction x y in Refl
export
proofPlusCommutative : (x, y : Natural) -> plus x y = plus y x
proofPlusCommutative x Zero = rewrite proofPlusLeftIdentity x in Refl
proofPlusCommutative x (Succesor y) =
rewrite proofPlusCommutative x y in
rewrite proofPlusLeftReduction y x in
Refl
export
proofPlusAssociative : (x, y, z : Natural)
-> plus x (plus y z) = plus (plus x y) z
proofPlusAssociative _ _ Zero = Refl
proofPlusAssociative x y (Succesor z) =
rewrite proofPlusAssociative x y z in Refl
public export
[NaturalSumMagma] Magma Natural where
(<>) = plus
public export
[NaturalSumCommutativeMagma] CommutativeMagma Natural using NaturalSumMagma where
proofCommutative = proofPlusCommutative
public export
[NaturalSumSemigroup] Semigroup Natural using NaturalSumMagma where
proofAssociative = proofPlusAssociative
public export
[NaturalSumCommutativeSemigroup] CommutativeSemigroup Natural using NaturalSumCommutativeMagma NaturalSumSemigroup where
public export
[NaturalSumMonoid] Monoid Natural using NaturalSumSemigroup where
id = Zero
proofLeftIdentity = proofPlusLeftIdentity
proofRightIdentity _ = Refl
public export
[NaturalSumCommutativeMonoid] CommutativeMonoid Natural using NaturalSumCommutativeSemigroup NaturalSumMonoid where
public export
minus : (x, y : Natural) -> {auto ok : x `GTE` y} -> Natural
minus x Zero = x
minus (Succesor x) (Succesor y) {ok=(SuccesorLTE p)} = minus x y
public export
mult : (x, y : Natural) -> Natural
mult _ Zero = Zero
mult x (Succesor y) = x `plus` mult x y
export
proofMultLeftIdentity : (x : Natural) -> mult (Succesor Zero) x = x
proofMultLeftIdentity Zero = Refl
proofMultLeftIdentity (Succesor x) =
rewrite proofMultLeftIdentity x in
rewrite proofPlusLeftReduction Zero x in
rewrite proofPlusLeftIdentity x in
Refl
export
proofMultLeftAnnihilation : (x : Natural) -> mult Zero x = Zero
proofMultLeftAnnihilation Zero = Refl
proofMultLeftAnnihilation (Succesor x) =
rewrite proofMultLeftAnnihilation x in Refl
export
proofMultRightAnnihilation : (x : Natural) -> mult x Zero = Zero
proofMultRightAnnihilation Zero = Refl
proofMultRightAnnihilation (Succesor x) =
rewrite proofMultRightAnnihilation x in Refl
export
proofMultCommutative : (x, y : Natural) -> mult x y = mult y x
proofMultCommutative Zero Zero = Refl
proofMultCommutative Zero (Succesor y) =
rewrite proofMultCommutative Zero y in Refl
proofMultCommutative (Succesor x) Zero =
rewrite proofMultCommutative Zero x in Refl
proofMultCommutative (Succesor x) (Succesor y) =
rewrite proofPlusLeftReduction x (mult (Succesor x) y) in
rewrite proofPlusLeftReduction y (mult (Succesor y) x) in
rewrite proofMultCommutative (Succesor x) y in
rewrite proofMultCommutative (Succesor y) x in
rewrite proofMultCommutative x y in
rewrite proofPlusAssociative x y (mult y x) in
rewrite proofPlusAssociative y x (mult y x) in
rewrite proofPlusCommutative x y in
Refl
export
proofMultLeftReduction : (x, y : Natural)
-> mult (Succesor x) y = plus y (mult x y)
proofMultLeftReduction x y =
rewrite proofMultCommutative (Succesor x) y in
rewrite proofMultCommutative x y in
Refl
export
proofMultLeftDistributesPlus : (x, y, z : Natural)
-> mult x (plus y z) = plus (mult x y) (mult x z)
proofMultLeftDistributesPlus Zero y z =
rewrite proofMultLeftAnnihilation y in
rewrite proofMultLeftAnnihilation z in
rewrite proofMultLeftAnnihilation (plus y z) in
Refl
proofMultLeftDistributesPlus (Succesor x) y z =
rewrite proofMultLeftReduction x y in
rewrite proofMultLeftReduction x z in
rewrite proofMultLeftReduction x (plus y z) in
rewrite proofMultLeftDistributesPlus x y z in
rewrite proofPlusAssociative (plus y (mult x y)) z (mult x z) in
rewrite proofPlusCommutative (plus y (mult x y)) z in
rewrite proofPlusAssociative z y (mult x y) in
rewrite proofPlusCommutative z y in
rewrite proofPlusAssociative (plus y z) (mult x y) (mult x z) in
Refl
proofMultRightDistributesPlus : (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 in
rewrite proofMultLeftDistributesPlus z x y in
rewrite proofMultCommutative z x in
rewrite proofMultCommutative z y in
Refl
public export
[NaturalMultMagma] Magma Natural where
(<>) = mult
public export
[NaturalMultSemigroup] Semigroup Natural using NaturalMultMagma where
proofAssociative x y Zero = Refl
proofAssociative x y (Succesor z) =
rewrite proofMultLeftDistributesPlus x y (mult y z) in
rewrite proofAssociative x y z in
Refl
public export
[NaturalMultMonoid] Monoid Natural using NaturalMultSemigroup where
id = Succesor Zero
proofLeftIdentity = proofMultLeftIdentity
proofRightIdentity _ = Refl
public export
divRem : (x, y : Natural) -> {auto ok : NotZero y} -> (Natural, Natural)
divRem x y = case decLTE y x of
Yes _ => let (d, r) := divRem (x `minus` y) y in (Succesor d, r)
No _ => (Zero, x)
public export
div : (x, y : Natural) -> {auto ok : NotZero y} -> Natural
div x y = fst $ divRem x y
public export
rem : (x, y : Natural) -> {auto ok : NotZero y} -> Natural
rem x y = snd $ divRem x y
public export
Semiring Natural where
(+) = plus
(*) = mult
zero = 0
one = 1
proofSumZero = proofRightIdentity @{NaturalSumMonoid}
proofSumCommutative = proofCommutative @{NaturalSumCommutativeMagma}
proofSumAssociative = proofAssociative @{NaturalSumSemigroup}
proofMultOneLeft = proofLeftIdentity @{NaturalMultMonoid}
proofMultOneRight = proofRightIdentity @{NaturalMultMonoid}
proofMultAssociative = proofAssociative @{NaturalMultSemigroup}
proofMultDistributesSumLeft = proofMultLeftDistributesPlus
proofMultDistributesSumRight = proofMultRightDistributesPlus
zeroAnnihilatorLeft = proofMultLeftAnnihilation
zeroAnnihilatorRight = proofMultRightAnnihilation
import public Data.Natural.SupportPrimIntegerLiteral
import public Data.Natural.Show
module Data.Natural.SupportPrimIntegerLiteral
import Builtin
import Algebra.Relation.Preorder
import Data.PrimInteger
import public Data.Natural.Basic
%default total
public export
natFromPrimInteger : (x : Integer) -> {auto ok : x `GTE` 0} -> Natural
natFromPrimInteger 0 = Zero
natFromPrimInteger x = case (decGTE (prim__sub_Integer x 1) 0) of
Yes p => Succesor $ assert_total $ natFromPrimInteger $ prim__sub_Integer x 1
No cp => void $ believe_me () -- TODO: impossible
-- TODO: Compiler not happy
-- %builtin IntegerToNatural natFromPrimInteger
public export
natToPrimInteger : Natural -> Integer
natToPrimInteger Zero = 0
natToPrimInteger (Succesor x) = prim__add_Integer 1 $ natToPrimInteger x
-- TODO: Compiler not happy
-- %builtin NaturalToInteger natToPrimInteger
public export
SupportPrimIntegerLiteral Natural where
PrimIntegerRestriction x = x `GTE` 0
fromPrimInteger = natFromPrimInteger
toPrimInteger = natToPrimInteger
module Data.Natural.Show
import Builtin
import Control.Show
import Data.PrimInteger
import public Data.Natural.SupportPrimIntegerLiteral
public export
Show Natural where
show = show . toPrimInteger
module Data.Natural.Semiring
import Builtin
import Algebra.Group.Magma
import Algebra.Group.Semigroup
import Algebra.Group.Monoid
import Algebra.Ring.Semiring
import public Data.Natural.Basic
import public Data.Natural.Group
%default total
public export
Semiring Natural where
(+) = add
(*) = mult
zero = Zero
one = (Succesor Zero)
proofSumZero = proofRightIdentity @{NaturalSumMonoid}
proofSumCommutative = proofCommutative @{NaturalSumCommutativeMagma}
proofSumAssociative = proofAssociative @{NaturalSumSemigroup}
proofMultOneLeft = proofLeftIdentity @{NaturalMultMonoid}
proofMultOneRight = proofRightIdentity @{NaturalMultMonoid}
proofMultAssociative = proofAssociative @{NaturalMultSemigroup}
proofMultDistributesSumLeft = proofMultLeftDistributesAdd
proofMultDistributesSumRight = proofMultRightDistributesAdd
zeroAnnihilatorLeft = proofMultLeftAnnihilation
zeroAnnihilatorRight = proofMultRightAnnihilation
module Data.Natural.Order
import Builtin
import Algebra.Relation.Equivalence
import Algebra.Relation.Preorder
import Algebra.Relation.Order
import public Data.Natural.Basic
import public Data.Natural.Equivalence
%default total
public export
data NaturalLTE : (x, y : Natural) -> Type where
ZeroLTEAny : NaturalLTE Zero y
SuccesorLTE : NaturalLTE x y -> NaturalLTE (Succesor x) (Succesor y)
public export
Uninhabited (NaturalLTE (Succesor y) Zero) where
uninhabited ZeroLTEAny impossible
uninhabited (SuccesorLTE _) impossible
export
proofLTEThenLTESuccesor : NaturalLTE x y -> NaturalLTE x (Succesor y)
proofLTEThenLTESuccesor ZeroLTEAny = ZeroLTEAny
proofLTEThenLTESuccesor (SuccesorLTE p) = SuccesorLTE $ proofLTEThenLTESuccesor p
export
proofNotLTEThenNotSuccesorLTE : Not (NaturalLTE x y) -> Not (NaturalLTE (Succesor x) (Succesor y))
proofNotLTEThenNotSuccesorLTE h (SuccesorLTE ctra) = h ctra
public export
Preorder Natural where
LTE = NaturalLTE
decLTE Zero y = Yes ZeroLTEAny
decLTE (Succesor _) Zero = No absurd
decLTE (Succesor x) (Succesor y) =
case decLTE x y of
Yes p => Yes $ SuccesorLTE p
No cp => No $ proofNotLTEThenNotSuccesorLTE cp
proofReflexivity Zero = ZeroLTEAny
proofReflexivity (Succesor x) = SuccesorLTE $ proofReflexivity x
proofTransitivity Zero Zero _ ZeroLTEAny ZeroLTEAny = ZeroLTEAny
proofTransitivity Zero (Succesor _) (Succesor _) ZeroLTEAny (SuccesorLTE _) = ZeroLTEAny
proofTransitivity (Succesor x) (Succesor y) (Succesor z) (SuccesorLTE p1) (SuccesorLTE p2) =
SuccesorLTE $ proofTransitivity x y z p1 p2
public export
Order Natural where
LT x = NaturalLTE (Succesor x)
decLT Zero Zero = No absurd
decLT Zero (Succesor _) = Yes $ SuccesorLTE ZeroLTEAny
decLT (Succesor _) Zero = No absurd
decLT (Succesor x) (Succesor y) =
case decLT x y of
Yes p => Yes $ SuccesorLTE p
No cp => No $ proofNotLTEThenNotSuccesorLTE cp
proofAntisymetry Zero Zero ZeroLTEAny ZeroLTEAny = BothZero
proofAntisymetry (Succesor x) (Succesor y) (SuccesorLTE p1) (SuccesorLTE p2) =
SuccesorEquiv $ proofAntisymetry x y p1 p2
proofLTThenLTE (SuccesorLTE p) = proofLTEThenLTESuccesor p
proofLTEThenLTOrEquiv Zero Zero ZeroLTEAny = Right BothZero
proofLTEThenLTOrEquiv Zero (Succesor _) ZeroLTEAny = Left $ SuccesorLTE ZeroLTEAny
proofLTEThenLTOrEquiv (Succesor x) (Succesor y) (SuccesorLTE p) =
case proofLTEThenLTOrEquiv x y p of
Left l => Left $ SuccesorLTE l
Right e => Right $ SuccesorEquiv e
module Data.Natural.Group
import Builtin
import Algebra.Group.Magma
import Algebra.Group.Semigroup
import Algebra.Group.Monoid
import public Data.Natural.Basic
public export
[NaturalSumMagma] Magma Natural where
(<>) = add
public export
[NaturalSumCommutativeMagma] CommutativeMagma Natural using NaturalSumMagma where
proofCommutative = proofAddCommutative
public export
[NaturalSumSemigroup] Semigroup Natural using NaturalSumMagma where
proofAssociative = proofAddAssociative
public export
[NaturalSumCommutativeSemigroup] CommutativeSemigroup Natural using NaturalSumCommutativeMagma NaturalSumSemigroup where
public export
[NaturalSumMonoid] Monoid Natural using NaturalSumSemigroup where
id = Zero
proofLeftIdentity = proofAddLeftIdentity
proofRightIdentity _ = Refl
public export
[NaturalSumCommutativeMonoid] CommutativeMonoid Natural using NaturalSumCommutativeSemigroup NaturalSumMonoid where
public export
[NaturalMultMagma] Magma Natural where
(<>) = mult
public export
[NaturalMultSemigroup] Semigroup Natural using NaturalMultMagma where
proofAssociative x y Zero = Refl
proofAssociative x y (Succesor z) =
rewrite proofMultLeftDistributesAdd x y (mult y z) in
rewrite proofAssociative x y z in
Refl
public export
[NaturalMultMonoid] Monoid Natural using NaturalMultSemigroup where
id = Succesor Zero
proofLeftIdentity = proofMultLeftIdentity
proofRightIdentity _ = Refl
module Data.Natural.ExtraOperations
import Builtin
import Algebra.Relation.Preorder
import public Data.Natural.Basic
import public Data.Natural.Order
%default total
public export
minus : (x, y : Natural) -> {auto ok : x `GTE` y} -> Natural
minus x Zero = x
minus (Succesor x) (Succesor y) {ok=(SuccesorLTE p)} = minus x y
public export
divRem : (x, y : Natural) -> {auto ok : NotZero y} -> (Natural, Natural)
divRem x y = case decLTE y x of
Yes _ => let (d, r) := divRem (x `minus` y) y in (Succesor d, r)
No _ => (Zero, x)
public export
div : (x, y : Natural) -> {auto ok : NotZero y} -> Natural
div x y = fst $ divRem x y
public export
rem : (x, y : Natural) -> {auto ok : NotZero y} -> Natural
rem x y = snd $ divRem x y
module Data.Natural.Equivalence
import Builtin
import Algebra.Relation.Equivalence
import public Data.Natural.Basic
public export
data NaturalEquiv : (x, y : Natural) -> Type where
BothZero : NaturalEquiv Zero Zero
SuccesorEquiv : NaturalEquiv x y -> NaturalEquiv (Succesor x) (Succesor y)
public export
Uninhabited (NaturalEquiv Zero (Succesor y)) where
uninhabited BothZero impossible
uninhabited (SuccesorEquiv _) impossible
public export
Uninhabited (NaturalEquiv (Succesor y) Zero) where
uninhabited BothZero impossible
uninhabited (SuccesorEquiv _) impossible
export
proofNotEquivThenNotSuccesorEquiv : {x, y : Natural}
-> Not (NaturalEquiv x y)
-> Not (NaturalEquiv (Succesor x) (Succesor y))
proofNotEquivThenNotSuccesorEquiv h (SuccesorEquiv ctra) = h ctra
public export
Equivalence Natural where
Equiv = NaturalEquiv
decEquiv Zero Zero = Yes BothZero
decEquiv Zero (Succesor _) = No absurd
decEquiv (Succesor _) Zero = No absurd
decEquiv (Succesor x) (Succesor y) =
case decEquiv x y of
Yes p => Yes $ SuccesorEquiv p
No cp => No $ proofNotEquivThenNotSuccesorEquiv cp
module Data.Natural.Basic
import Builtin
%default total
public export
data Natural = Zero | Succesor Natural
%builtin Natural Natural
--
-- Restrictions
--
public export
data NotZero : Natural -> Type where
IsNotZero : NotZero (Succesor _)
public export
Uninhabited (NotZero Zero) where
uninhabited IsNotZero impossible
--
-- Operations
--
-- Addition
public export
add : (x, y : Natural) -> Natural
add x Zero = x
add x (Succesor y) = Succesor $ add x y
export
proofAddLeftIdentity : (x : Natural) -> add Zero x = x
proofAddLeftIdentity Zero = Refl
proofAddLeftIdentity (Succesor x) = rewrite proofAddLeftIdentity x in Refl
export
proofAddLeftReduction : (x, y : Natural)
-> add (Succesor x) y = Succesor (add x y)
proofAddLeftReduction x Zero = Refl
proofAddLeftReduction x (Succesor y) =
rewrite proofAddLeftReduction x y in Refl
export
proofAddCommutative : (x, y : Natural) -> add x y = add y x
proofAddCommutative x Zero = rewrite proofAddLeftIdentity x in Refl
proofAddCommutative x (Succesor y) =
rewrite proofAddCommutative x y in
rewrite proofAddLeftReduction y x in
Refl
export
proofAddAssociative : (x, y, z : Natural)
-> add x (add y z) = add (add x y) z
proofAddAssociative _ _ Zero = Refl
proofAddAssociative x y (Succesor z) =
rewrite proofAddAssociative x y z in Refl
-- Diff
public export
diff : (x, y : Natural) -> Natural
diff Zero y = y
diff x Zero = x
diff (Succesor x) (Succesor y) = diff x y
-- Mult
public export
mult : (x, y : Natural) -> Natural
mult _ Zero = Zero
mult x (Succesor y) = x `add` mult x y
export
proofMultLeftIdentity : (x : Natural) -> mult (Succesor Zero) x = x
proofMultLeftIdentity Zero = Refl
proofMultLeftIdentity (Succesor x) =
rewrite proofMultLeftIdentity x in
rewrite proofAddLeftReduction Zero x in
rewrite proofAddLeftIdentity x in
Refl
export
proofMultLeftAnnihilation : (x : Natural) -> mult Zero x = Zero
proofMultLeftAnnihilation Zero = Refl
proofMultLeftAnnihilation (Succesor x) =
rewrite proofMultLeftAnnihilation x in Refl
export
proofMultRightAnnihilation : (x : Natural) -> mult x Zero = Zero
proofMultRightAnnihilation Zero = Refl
proofMultRightAnnihilation (Succesor x) =
rewrite proofMultRightAnnihilation x in Refl
export
proofMultCommutative : (x, y : Natural) -> mult x y = mult y x
proofMultCommutative Zero Zero = Refl
proofMultCommutative Zero (Succesor y) =
rewrite proofMultCommutative Zero y in Refl
proofMultCommutative (Succesor x) Zero =
rewrite proofMultCommutative Zero x in Refl
proofMultCommutative (Succesor x) (Succesor y) =
rewrite proofAddLeftReduction x (mult (Succesor x) y) in
rewrite proofAddLeftReduction y (mult (Succesor y) x) in
rewrite proofMultCommutative (Succesor x) y in
rewrite proofMultCommutative (Succesor y) x in
rewrite proofMultCommutative x y in
rewrite proofAddAssociative x y (mult y x) in
rewrite proofAddAssociative y x (mult y x) in
rewrite proofAddCommutative x y in
Refl
export
proofMultLeftReduction : (x, y : Natural)
-> mult (Succesor x) y = add y (mult x y)
proofMultLeftReduction x y =
rewrite proofMultCommutative (Succesor x) y in
rewrite proofMultCommutative x y in
Refl
export
proofMultLeftDistributesAdd : (x, y, z : Natural)
-> mult x (add y z) = add (mult x y) (mult x z)
proofMultLeftDistributesAdd Zero y z =
rewrite proofMultLeftAnnihilation y in
rewrite proofMultLeftAnnihilation z in
rewrite proofMultLeftAnnihilation (add y z) in
Refl
proofMultLeftDistributesAdd (Succesor x) y z =
rewrite proofMultLeftReduction x y in
rewrite proofMultLeftReduction x z in
rewrite proofMultLeftReduction x (add y z) in
rewrite proofMultLeftDistributesAdd x y z in
rewrite proofAddAssociative (add y (mult x y)) z (mult x z) in
rewrite proofAddCommutative (add y (mult x y)) z in
rewrite proofAddAssociative z y (mult x y) in
rewrite proofAddCommutative z y in
rewrite proofAddAssociative (add y z) (mult x y) (mult x z) in
Refl
export
proofMultRightDistributesAdd : (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 in
rewrite proofMultLeftDistributesAdd z x y in
rewrite proofMultCommutative z x in
rewrite proofMultCommutative z y in
Refl