-- This is a simple example which illustrates the use of propositions as types -- and representation of ideas of Gentzen for natural deduction in lambda calculus -- modus ponens is application -- we also use Set both as a type of types and of propositions -- we represent the true proposition ⊤ as a data type having one constructor and the false proposition ⊥ -- having no constructor {-# OPTIONS --allow-unsolved-metas #-} module euclidean where open import Agda.Primitive renaming(Set to Type) symmetric : (X : Type) → (X → X → Type) → Type symmetric X R = (a b : X) → R a b → R b a -- (a : X) → (b : X) → R a b → R b a reflexive : (X : Type) → (X → X → Type) → Type reflexive X R = (x : X) → R x x transitive : (X : Type) → (X → X → Type) → Type transitive X R = (a b c : X) → R a b → R b c → R a c euclidean : (X : Type) → (X → X → Type) → Type euclidean X R = (a b c : X) → R a b → R a c → R b c theorem1 : (A : Type) → (Eq : A → A → Type) → euclidean A Eq → reflexive A Eq → symmetric A Eq theorem1 A Eq eucl refl a b Eab = {!!} -- eucl a b a Eab (refl a) -- not that symmetric has been silently unfolded -- this is a special feature of Agda -- this is also called the "Poincare Principle" -- here is a famous example from Leibniz: the statement 2 + 2 = 4 is analytic data Nat : Type where zero : Nat succ : Nat → Nat -- one : Nat one = succ zero two = succ one three = succ two four = succ three add : Nat → Nat → Nat add x zero = x add x (succ y) = succ (add x y) -- what is the normal form of add two two and the normal form of four? theorem2 : (A : Type) → (Eq : A → A → Type) → euclidean A Eq → reflexive A Eq → transitive A Eq theorem2 A Eq eucl refl a b c Eab Ebc = {!!} -- eucl b a c (theorem1 A Eq eucl refl a b Eab) Ebc -- counter-example: a relation can be euclidean and not symmetric if it is not reflexive data CA : Type where Ca Cb : CA data ⊥ : Type where data ⊤ : Type where tt : ⊤ -- relation containing only (Ca, Cb) and (Cb, Cb) -- in set theory CA = {Ca, Cb} and CEq = { (Ca,Cb), (Cb,Cb) } CEq : CA → CA → Type CEq Ca Ca = ⊥ CEq Ca Cb = ⊤ CEq Cb Ca = ⊥ CEq Cb Cb = ⊤ -- we have then 7 cases to consider remark1 : euclidean CA CEq remark1 Ca Ca c () CEac remark1 Ca Cb Ca CEab () remark1 Ca Cb Cb CEab CEac = tt remark1 Cb Ca Ca () CEac remark1 Cb Ca Cb () CEac remark1 Cb Cb Ca CEab () remark1 Cb Cb Cb CEab CEac = tt