x == y
eq_op : (T : Type) -> (x y : T) -> bool Notation "x == y" := (eq_op _ x y).
eq_op
is not possible to implement in generalStructure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }.
Inductive eqType := Pack : forall (sort : Type) (eq_op : sort -> sort -> bool) (spec : forall x y, reflect (x = y) (eq_op x y)), eqType. Definition sort (e : eqType) : Type := let (sort, _, _) := e in sort. (* and `eq_op` and `spec` projections *)
Structure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }.
Structure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }. Coercion sort : eqType >-> Sortclass.
Structure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }. Coercion sort : eqType >-> Sortclass. Lemma eq_sym (T : eqType) (x y : T) : x == y -> y == x.
Structure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }. Coercion sort : eqType >-> Sortclass. Lemma eq_sym (T : eqType) (x y : sort T) : x == y -> y == x.
Structure eqType := Pack { sort : Type; eq_op : sort -> sort -> bool; spec : forall x y, reflect (x = y) (eq_op x y) }.
eq_op : forall {T : eqType}, sort T -> sort T -> bool
initially we have
1 == 2
unfold ==
notation
@eq_op _ 1 2 (* 1 == 2 *)
unfold ==
notation
eq_op _ 1 2
@eq_op : forall (T : eqType), sort T -> sort T -> bool
add types and names
eq_op (?T : eqType) (1 : sort ?T) (2 : sort ?T)
add types and names
eq_op (?T : eqType) (1 : sort ?T) (2 : sort ?T) eq_op (?T : eqType) (1 : nat) (2 : nat)
so we need to be able to solve equations like
sort (?T : eqType) ≡ nat
Canonical nat_eqType := Pack nat eqn proof. Print Canonical Projections. ... nat <- sort ( nat_eqType ) ...
Print Canonical Projections sort. nat <- sort ( nat_eqType )
eq_op (?T : eqType) (1 : sort ?T) (2 : sort ?T) eq_op (?T : eqType) (1 : nat) (2 : nat)
nat <- sort ( nat_eqType ) eq_op (?T : eqType) (1 : sort ?T) (2 : sort ?T) | | v v eq_op (?T : eqType) (1 : nat) (2 : nat)
nat <- sort ( nat_eqType ) eq_op (nat_eqType : eqType) (1 : sort nat_eqType) (2 : sort nat_eqType)
Definition pair_eq (A B : eqType) (u v : A * B) := (u.1 == v.1) && (u.2 == v.2).
Definition pair_eq (A B : eqType) (u v : A * B) := (u.1 == v.1) && (u.2 == v.2). Canonical prod_eqType A B := Pack (A * B) pair_eq proof.
Definition pair_eq (A B : eqType) (u v : sort A * sort B) := (u.1 == v.1) && (u.2 == v.2). Canonical prod_eqType A B := Pack (sort A * sort B) pair_eq proof.
Definition pair_eq (A B : eqType) (u v : sort A * sort B) := (u.1 == v.1) && (u.2 == v.2). Canonical prod_eqType A B := Pack (sort A * sort B) pair_eq proof. Print Canonical Projections sort. nat <- sort ( nat_eqType ) prod <- sort ( prod_eqType )
Definition pair_eq (A B : eqType) (u v:prod (sort A) (sort B)) := (u.1 == v.1) && (u.2 == v.2). Canonical prod_eqType A B := Pack (prod (sort A) (sort B)) pair_eq proof. Print Canonical Projections sort. nat <- sort ( nat_eqType ) prod <- sort ( prod_eqType )
Canonical bool_eqType := Pack bool eqb proof.
Compute (1, true) == (1, true).
Compute (1, true) == (1, true). true
(1, true) == (1, true)
desugars into
eq_op _ (1, true) (1, true)
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ...
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. nat * bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. nat * bool sort ?T ≡ nat * bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType )
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType ) sort (prod_eqType ?A ?B) ≡ prod nat bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType ) sort (prod_eqType ?A ?B) ≡ prod nat bool (sort ?A) * (sort ?B) ≡ prod nat bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType ) sort (prod_eqType ?A ?B) ≡ prod nat bool prod (sort ?A) (sort ?B) ≡ prod nat bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType ) sort (prod_eqType ?A ?B) ≡ prod nat bool prod (sort ?A) (sort ?B) ≡ prod nat bool (sort ?A) ≡ nat (sort ?B) ≡ bool
eq_op : (?T : eqType) -> (x y:sort ?T) -> bool eq_op _ (1, true) ... .. prod nat bool sort ?T ≡ prod nat bool prod <- sort ( prod_eqType ) sort (prod_eqType ?A ?B) ≡ prod nat bool prod (sort ?A) (sort ?B) ≡ prod nat bool (sort ?A) ≡ nat (sort ?B) ≡ bool ?A ≡ nat_eqType ?B ≡ bool_eqType
eauto
-like proof search and may even loop forever
Mathcomp's bigop
module defines monoids like so:
Module Monoid. ... Structure law (T : Type) (idm : T) : Type := Law { operator : T -> T -> T; _ : associative operator; _ : left_id idm operator; _ : right_id idm operator }. ... End Monoid.
Here are some instances on nat
:
Canonical addn_monoid := Law addnA add0n addn0. Canonical muln_monoid := Law mulnA mul1n muln1. Canonical maxn_monoid := Law maxnA max0n maxn0.
newtype
operator
is the key for canonical instances search
Print Canonical Projections operator. cat <- operator ( cat_monoid ) div.lcmn <- operator ( lcmn_monoid ) div.gcdn <- operator ( gcdn_monoid ) maxn <- operator ( maxn_monoid ) muln <- operator ( muln_monoid ) addn <- operator ( addn_monoid ) addb <- operator ( addb_monoid ) orb <- operator ( orb_monoid ) andb <- operator ( andb_monoid )
From mathcomp Require Import ssreflect ssrnat bigop. Import Monoid. Lemma foo m n p q r : m + (n + p * (q * r)) = m + n + p * q * r. Proof. by rewrite !mulmA /=. Qed.
Structure structure := Pack { sort : Type; _ : class_of sort }.
Record class_of T := Class { base : Parent.class_of T; mixin : mixin_of T }.
Record mixin_of T := Mixin { ... }.
ordType
earlier: it's parent is choiceType
, not eqType
Definition eq_axiom T (e : rel T) := forall x y, reflect (x = y) (e x y). HB.mixin Record HasDecEq T := { eq_op : rel T; eqP : eq_axiom eq_op }. HB.structure Definition Equality := { T of HasDecEq T }.
eqType
and subType
choiceType
(e.g. finite maps on types with choice operator)ordType