Now, `universe` may declare many universes. The goal is to make it consistent with the `variable` command
69 lines
1.3 KiB
Text
69 lines
1.3 KiB
Text
/- Coercion pullback example from the paper "Hints in Unification" -/
|
||
|
||
universe u
|
||
|
||
structure Monoid where
|
||
α : Type u
|
||
op : α → α → α
|
||
unit : α
|
||
|
||
structure Group where
|
||
α : Type u
|
||
op : α → α → α
|
||
unit : α
|
||
inv : α → α
|
||
|
||
structure Ring where
|
||
α : Type u
|
||
mul : α → α → α
|
||
add : α → α → α
|
||
neg : α → α
|
||
one : α
|
||
zero : α
|
||
|
||
def Group.ofRing (r : Ring) : Group where
|
||
α := r.α
|
||
op := r.add
|
||
inv := r.neg
|
||
unit := r.zero
|
||
|
||
def Monoid.ofRing (r : Ring) : Monoid where
|
||
α := r.α
|
||
op := r.mul
|
||
unit := r.one
|
||
|
||
instance : CoeSort Ring (Type u) where
|
||
coe s := s.α
|
||
|
||
instance : CoeSort Monoid (Type u) where
|
||
coe s := s.α
|
||
|
||
instance : CoeSort Group (Type u) where
|
||
coe s := s.α
|
||
|
||
def gop {s : Group} (a b : s) : s :=
|
||
s.op a b
|
||
|
||
def mop {s : Monoid} (a b : s) : s :=
|
||
s.op a b
|
||
|
||
infix:70 (priority := high) "*" => mop
|
||
infix:65 (priority := high) "+" => gop
|
||
|
||
unif_hint (r : Ring) (g : Group) where
|
||
g =?= Group.ofRing r
|
||
|-
|
||
r.α =?= g.α
|
||
|
||
unif_hint (r : Ring) (m : Monoid) where
|
||
m =?= Monoid.ofRing r
|
||
|-
|
||
r.α =?= m.α
|
||
|
||
def distrib {r : Ring} (a b c : r) := a * (b + c) = a * b + a * c
|
||
|
||
theorem ex1 {r : Ring} (a b c : r) : distrib a b c = (a * (b + c) = a * b + a * c) :=
|
||
rfl
|
||
|
||
theorem ex2 {r : Ring} (a b c : r) : distrib a b c = (mop a (gop b c) = gop (mop a b) (mop a c)) :=
|
||
rfl
|