1
Fork 0
solar-conflux/idris/learning/src/My/Integers.idr

208 lines
6 KiB
Idris
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module My.Integers
import My.Nats
import My.Structures
import Syntax.PreorderReasoning
import My.Syntax.Rewrite
import My.Signs
%default total
public export
: Type
= (, )
public export
addIntegers : -> ->
addIntegers (x, y) (z, w) = (x + z, y + w)
public export
toNat : -> (Sign, )
toNat (Z, S x) = (Negative, S x)
toNat (x, Z) = (Positive, x)
toNat ((S x), (S y)) = toNat $ assert_smaller (S x, S y) (x, y)
public export
multiplyIntegers : -> ->
multiplyIntegers (x, y) (z, w) = (x * z + y * w, x * w + y * z)
public export
negateInteger : ->
negateInteger (x, y) = (y, x)
public export
substractIntegers : -> ->
substractIntegers a b = (?l, ?r)
public export
normalForm : ->
normalForm ((S x), (S y)) = normalForm (assert_smaller (S x, S y) (x, y))
normalForm a = a
-- absoluteValue : ->
-- absoluteValue (Z, b) = b
-- absoluteValue ((S x), y) = absoluteValue (x, y)
public export
fromNat : ->
fromNat n = (n, Z)
public export
fromActualInteger : Integer ->
fromActualInteger 0 = (Z, Z)
fromActualInteger n =
if n > 0 then
fromNat (fromInteger n)
else
negateInteger (fromNat (fromInteger (-n)))
public export
Num where
(+) = addIntegers
(*) = multiplyIntegers
fromInteger = fromActualInteger
public export
Neg where
negate = negateInteger
(-) = substractIntegers
---------- Equivalence
public export
integersAreEquivalent : -> -> Type
integersAreEquivalent (x, y) (z, w) = x + w = z + y
public export
equivalenceIsReflexive : integersAreEquivalent a a
equivalenceIsReflexive {a = (x, y)} = Refl
public export
equivalenceIsTransitive : {a, b, c: } -> integersAreEquivalent a b -> integersAreEquivalent b c -> integersAreEquivalent a c
equivalenceIsTransitive {a = (z, w)} {b = (v, s)} {c = (t, u)} zsISvw vuISts = id
$(z + u = t + w)
$ My.Nats.substractionPreservesEquality s
$((z + u) + s = (t + w) + s)
$ rewrite My.Nats.additionIsCommutative z u
in …l ((u + z) + s)
$ rewrite My.Nats.additionIsAssociative u z s
in …l (u + (z + s))
$ rewrite zsISvw
in …l (u + (v + w))
$ rewrite sym $ My.Nats.additionIsAssociative u v w
in …l ((u + v) + w)
$ rewrite My.Nats.additionIsCommutative t w
in …r ((w + t) + s)
$ rewrite My.Nats.additionIsAssociative w t s
in …r (w + (t + s))
$ rewrite My.Nats.additionIsCommutative w (t + s)
in …r ((t + s) + w)
$ My.Nats.additionPreservesEquality w
$(u + v = t + s)
$ rewrite My.Nats.additionIsCommutative u v
in …l (v + u)
$ vuISts
public export
equivalenceIsSymmetric : {a, b: } -> integersAreEquivalent a b -> integersAreEquivalent b a
equivalenceIsSymmetric {a = (y, z)} {b = (w, v)} x = sym x
public export
My.Structures.Setoid where
(<->) = integersAreEquivalent
reflexivity = equivalenceIsReflexive
transitivity = equivalenceIsTransitive
symmetry = equivalenceIsSymmetric
---------- Addition proofs
public export
additionIsCommutative : CommutativityProof My.Integers.addIntegers
additionIsCommutative (Z, y) (x, z) = (x + (z + y) = (x + 0) + (y + z))
.... rewrite My.Nats.additionRightIdentity x in (x + (z + y) = x + (y + z))
.... rewrite My.Nats.additionIsCommutative y z in (x + (z + y) = x + (z + y))
.... Refl
additionIsCommutative ((S x), y) (z, w) = id
$(1 + ((x + z) + (w + y)) = (z + (1 + x)) + (y + w))
$ rewrite My.Nats.additionIsCommutative y w
in …r ((z + (1 + x)) + (w + y))
$ rewrite My.Nats.additionIsCommutative z (1 + x)
in …r (1 + (x + z) + (w + y))
$ Refl
public export
additionIsAssociative : AssociativityProof My.Integers.addIntegers
additionIsAssociative (x, y) (z, w) (v, s) = id
$((((x + z) + v) + (y + (w + s))) = ((x + (z + v) + ((y + w) + s))))
$ rewrite My.Nats.additionIsAssociative x z v
in …l ((x + (z + v) + (y + (w + s))))
$ rewrite My.Nats.additionIsAssociative y w s
in …r ((x + (z + v) + (y + (w + s))))
$ Refl
public export
additionRightIdentity : RightIdentityProof My.Integers.addIntegers 0
additionRightIdentity (x, y) = id
$((x + 0) + y = x + (y + 0))
$ rewrite My.Nats.additionRightIdentity x
in …l (x + y)
$ rewrite My.Nats.additionRightIdentity y
in …r (x + y)
$ Refl
public export
additionLeftIdentity : LeftIdentityProof My.Integers.addIntegers 0
additionLeftIdentity (x, y) = Refl
---------- Multiplication proofs
multiplyToNatResults : (Sign, ) -> (Sign, ) -> (Sign, )
multiplyToNatResults (x, z) (y, w) = (multiplySigns x y, z * w)
ToNatDistributesMultiplication : -> -> Type
ToNatDistributesMultiplication a b = toNat (a * b) = multiplyToNatResults (toNat a) (toNat b)
toNatDistributesMultiplication : (a, b: ) -> ToNatDistributesMultiplication a b
toNatDistributesMultiplication (Z, Z) (Z, Z) = Refl
toNatDistributesMultiplication (Z, Z) (Z, (S x)) = ?toNatDistributesMultiplication_rhs_9
toNatDistributesMultiplication (Z, Z) ((S x), w) = ?toNatDistributesMultiplication_rhs_7
toNatDistributesMultiplication (Z, (S x)) (z, w) = ?toNatDistributesMultiplication_rhs_5
toNatDistributesMultiplication ((S x), y) (z, w) = ?toNatDistributesMultiplication_rhs_3
multiplicationIsAssociative : AssociativityProof My.Integers.multiplyIntegers
multiplicationIsAssociative 0 b c = ?multiplicationIsAssociative_rhs
multiplicationIsAssociative a b c = ?multiplicationIsAssociative_rhs_1
---------- Interface implementations
public export
[additionSemigroup] My.Structures.Semigroup where
= addIntegers
associativityProof = additionIsAssociative
public export
[additionMonoid] My.Structures.Monoid using My.Integers.additionSemigroup where
empty = 0
rightIdentityProof = My.Integers.additionRightIdentity
leftIdentityProof = My.Integers.additionLeftIdentity
[multiplicationSemigroup] My.Structures.Semigroup where
= multiplyIntegers
associativityProof = multiplicationIsAssociative
---------- Constants to play around with
seven :
seven = 7
minusFour :
minusFour = -4
three :
three = 3
three' :
three' = minusFour + seven