include "algebra/monoids.ma".
include "nat/le_arith.ma".
-record isGroup (M:Monoid) (opp: M -> M) : Prop ≝
- { opp_is_left_inverse: is_left_inverse M opp;
- opp_is_right_inverse: is_right_inverse M opp
+record PreGroup : Type ≝
+ { premonoid:> PreMonoid;
+ opp: premonoid -> premonoid
+ }.
+
+record isGroup (G:PreGroup) : Prop ≝
+ { is_monoid: isMonoid G;
+ opp_is_left_inverse: is_left_inverse (mk_Monoid ? is_monoid) (opp G);
+ opp_is_right_inverse: is_right_inverse (mk_Monoid ? is_monoid) (opp G)
}.
record Group : Type ≝
- { monoid: Monoid;
- opp: monoid -> monoid;
- group_properties: isGroup ? opp
+ { pregroup:> PreGroup;
+ group_properties:> isGroup pregroup
}.
-coercion cic:/matita/algebra/groups/monoid.con.
-
-notation < "G"
+(*notation < "G"
for @{ 'monoid $G }.
interpretation "Monoid coercion" 'monoid G =
- (cic:/matita/algebra/groups/monoid.con G).
+ (cic:/matita/algebra/groups/monoid.con G).*)
notation < "G"
for @{ 'type_of_group $G }.
(cic:/matita/algebra/groups/Type_of_Group.con G).
notation < "G"
-for @{ 'semigroup_of_group $G }.
+for @{ 'magma_of_group $G }.
-interpretation "Semigroup_of_group coercion" 'semigroup_of_group G =
- (cic:/matita/algebra/groups/SemiGroup_of_Group.con G).
+interpretation "magma_of_group coercion" 'magma_of_group G =
+ (cic:/matita/algebra/groups/Magma_of_Group.con G).
notation "hvbox(x \sup (-1))" with precedence 89
for @{ 'gopp $x }.
unfold left_cancellable;
unfold injective;
intros (x y z);
-rewrite < (e_is_left_unit ? ? (monoid_properties G));
-rewrite < (e_is_left_unit ? ? (monoid_properties G) z);
-rewrite < (opp_is_left_inverse ? ? (group_properties G) x);
-rewrite > (semigroup_properties G);
-rewrite > (semigroup_properties G);
+rewrite < (e_is_left_unit ? (is_monoid ? (group_properties G)));
+rewrite < (e_is_left_unit ? (is_monoid ? (group_properties G)) z);
+rewrite < (opp_is_left_inverse ? (group_properties G) x);
+rewrite > (associative ? (is_semi_group ? (is_monoid ? (group_properties G))));
+rewrite > (associative ? (is_semi_group ? (is_monoid ? (group_properties G))));
apply eq_f;
assumption.
qed.
unfold injective;
simplify;fold simplify (op G);
intros (x y z);
-rewrite < (e_is_right_unit ? ? (monoid_properties G));
-rewrite < (e_is_right_unit ? ? (monoid_properties G) z);
-rewrite < (opp_is_right_inverse ? ? (group_properties G) x);
-rewrite < (semigroup_properties G);
-rewrite < (semigroup_properties G);
+rewrite < (e_is_right_unit ? (is_monoid ? (group_properties G)));
+rewrite < (e_is_right_unit ? (is_monoid ? (group_properties G)) z);
+rewrite < (opp_is_right_inverse ? (group_properties G) x);
+rewrite < (associative ? (is_semi_group ? (is_monoid ? (group_properties G))));
+rewrite < (associative ? (is_semi_group ? (is_monoid ? (group_properties G))));
rewrite > H;
reflexivity.
qed.
(cic:/matita/algebra/groups/order.con C _).
record finite_enumerable_SemiGroup : Type ≝
- { semigroup: SemiGroup;
- is_finite_enumerable: finite_enumerable semigroup
+ { semigroup:> SemiGroup;
+ is_finite_enumerable:> finite_enumerable semigroup
}.
-coercion cic:/matita/algebra/groups/semigroup.con.
-coercion cic:/matita/algebra/groups/is_finite_enumerable.con.
-
notation < "S"
for @{ 'semigroup_of_finite_enumerable_semigroup $S }.
=
(cic:/matita/algebra/groups/semigroup.con S).
+notation < "S"
+for @{ 'magma_of_finite_enumerable_semigroup $S }.
+
+interpretation "Magma_of_finite_enumerable_semigroup"
+ 'magma_of_finite_enumerable_semigroup S
+=
+ (cic:/matita/algebra/groups/Magma_of_finite_enumerable_SemiGroup.con S).
+
notation < "S"
for @{ 'type_of_finite_enumerable_semigroup $S }.
∀G:finite_enumerable_SemiGroup.
left_cancellable ? (op G) →
right_cancellable ? (op G) →
- ∃e:G. isMonoid G e.
+ ∃e:G. isMonoid (mk_PreMonoid G e).
intros;
letin f ≝ (λn.ι(G \sub O · G \sub n));
cut (∀n.n ≤ order ? (is_finite_enumerable G) → ∃m.f m = n);
clearbody GOGO;
rewrite < HH in GOGO;
rewrite < HH in GOGO:(? ? % ?);
- rewrite > (semigroup_properties G) in GOGO;
+ rewrite > (associative ? G) in GOGO;
letin GaGa ≝ (H ? ? ? GOGO);
clearbody GaGa;
clear GOGO;
constructor 1;
- [ unfold is_left_unit; intro;
+ [ simplify;
+ apply (semigroup_properties G)
+ | unfold is_left_unit; intro;
letin GaxGax ≝ (refl_eq ? (G \sub a ·x));
clearbody GaxGax;
rewrite < GaGa in GaxGax:(? ? % ?);
- rewrite > (semigroup_properties G) in GaxGax;
+ rewrite > (associative ? (semigroup_properties G)) in GaxGax;
apply (H ? ? ? GaxGax)
| unfold is_right_unit; intro;
letin GaxGax ≝ (refl_eq ? (x·G \sub a));
clearbody GaxGax;
rewrite < GaGa in GaxGax:(? ? % ?);
- rewrite < (semigroup_properties G) in GaxGax;
+ rewrite < (associative ? (semigroup_properties G)) in GaxGax;
apply (H1 ? ? ? GaxGax)
+ ]
]
|
-].
\ No newline at end of file
+].
include "algebra/semigroups.ma".
-record isMonoid (SS:SemiGroup) (e:SS) : Prop ≝
- { e_is_left_unit: is_left_unit SS e;
- e_is_right_unit: is_right_unit SS e
+record PreMonoid : Type ≝
+ { magma:> Magma;
+ e: magma
+ }.
+
+notation < "M" for @{ 'pmmagma $M }.
+interpretation "premonoid magma coercion" 'pmmagma M =
+ (cic:/matita/algebra/monoids/magma.con M).
+
+record isMonoid (M:PreMonoid) : Prop ≝
+ { is_semi_group: isSemiGroup M;
+ e_is_left_unit:
+ is_left_unit (mk_SemiGroup ? is_semi_group) (e M);
+ e_is_right_unit:
+ is_right_unit (mk_SemiGroup ? is_semi_group) (e M)
}.
record Monoid : Type ≝
- { semigroup: SemiGroup;
- e: semigroup;
- monoid_properties: isMonoid ? e
+ { premonoid:> PreMonoid;
+ monoid_properties:> isMonoid premonoid
}.
-
-coercion cic:/matita/algebra/monoids/semigroup.con.
-
-(* too ugly
-notation "hvbox(1 \sub S)" with precedence 89
-for @{ 'munit $S }.
-
-interpretation "Monoid unit" 'munit S =
- (cic:/matita/algebra/monoids/e.con S). *)
+notation < "M" for @{ 'semigroup $M }.
+interpretation "premonoid coercion" 'premonoid M =
+ (cic:/matita/algebra/monoids/premonoid.con M).
+
+notation < "M" for @{ 'typeofmonoid $M }.
+interpretation "premonoid coercion" 'typeofmonoid M =
+ (cic:/matita/algebra/monoids/Type_of_Monoid.con M).
+
+notation < "M" for @{ 'magmaofmonoid $M }.
+interpretation "premonoid coercion" 'magmaofmonoid M =
+ (cic:/matita/algebra/monoids/Magma_of_Monoid.con M).
+
notation "1" with precedence 89
for @{ 'munit }.
interpretation "Monoid unit" 'munit =
(cic:/matita/algebra/monoids/e.con _).
-notation < "M"
-for @{ 'semigroup $M }.
-
-interpretation "Semigroup coercion" 'semigroup M =
- (cic:/matita/algebra/monoids/semigroup.con M).
-
definition is_left_inverse ≝
λM:Monoid.
λopp: M → M.
generalize in match (eq_f ? ? (λy.y·(r x)) ? ? H2);
simplify; fold simplify (op M);
intro; clear H2;
- generalize in match (semigroup_properties M);
- fold simplify (Type_of_Monoid M);
+ generalize in match (associative ? (is_semi_group ? (monoid_properties M)));
intro;
- unfold isSemiGroup in H2; unfold associative in H2;
rewrite > H2 in H3; clear H2;
rewrite > H1 in H3;
- rewrite > (e_is_left_unit ? ? (monoid_properties M)) in H3;
- rewrite > (e_is_right_unit ? ? (monoid_properties M)) in H3;
+ rewrite > (e_is_left_unit ? (monoid_properties M)) in H3;
+ rewrite > (e_is_right_unit ? (monoid_properties M)) in H3;
assumption.
qed.
include "higher_order_defs/functions.ma".
-definition isSemiGroup ≝
- λC:Type. λop: C → C → C.associative C op.
+(* Magmas *)
-record SemiGroup : Type ≝
- { carrier: Type;
- op: carrier → carrier → carrier;
- semigroup_properties: isSemiGroup carrier op
+record Magma : Type ≝
+ { carrier:> Type;
+ op: carrier → carrier → carrier
}.
-
-coercion cic:/matita/algebra/semigroups/carrier.con.
-notation "hvbox(a break \middot \sub S b)"
- left associative with precedence 55
-for @{ 'ptimes $S $a $b }.
+notation < "M" for @{ 'carrier $M }.
+interpretation "carrier coercion" 'carrier S =
+ (cic:/matita/algebra/semigroups/carrier.con S).
notation "hvbox(a break \middot b)"
left associative with precedence 55
-for @{ 'ptimesi $a $b }.
+for @{ 'magma_op $a $b }.
-interpretation "Semigroup operation" 'ptimesi a b =
+interpretation "magma operation" 'magma_op a b =
(cic:/matita/algebra/semigroups/op.con _ a b).
-(* too ugly
-interpretation "Semigroup operation" 'ptimes S a b =
- (cic:/matita/algebra/semigroups/op.con S a b). *)
-
-notation < "S"
-for @{ 'carrier $S }.
+(* Semigroups *)
-interpretation "Carrier coercion" 'carrier S =
- (cic:/matita/algebra/semigroups/carrier.con S).
+record isSemiGroup (M:Magma) : Prop ≝
+ { associative: associative ? (op M) }.
+record SemiGroup : Type ≝
+ { magma:> Magma;
+ semigroup_properties:> isSemiGroup magma
+ }.
+
+notation < "S" for @{ 'magma $S }.
+interpretation "magma coercion" 'magma S =
+ (cic:/matita/algebra/semigroups/magma.con S).
+
definition is_left_unit ≝
λS:SemiGroup. λe:S. ∀x:S. e·x = x.
in
C.CoFix (i, fl')
in
- um_aux term
+ LibrarySync.merge_coercions (um_aux term)
;;
let apply_subst =
let newt, _, subst, metasenv, ugraph =
avoid_double_coercion
subst metasenv ugraph
- (Cic.Appl[c;hete]) tgt_carr
- in
- newt, subst, metasenv, ugraph)
+ (Cic.Appl[c;hete]) tgt_carr in
+ try
+ let newty,newhety,subst,metasenv,ugraph =
+ type_of_aux subst metasenv context newt ugraph in
+ let subst,metasenv,ugraph1 =
+ fo_unif_subst subst context metasenv
+ newhety s ugraph
+ in
+ newt, subst, metasenv, ugraph
+ with exn ->
+ enrich localization_tbl hete
+ ~f:(fun _ ->
+ (lazy ("The term " ^
+ CicMetaSubst.ppterm_in_context subst hete
+ context ^ " has type " ^
+ CicMetaSubst.ppterm_in_context subst hety
+ context ^ " but is here used with type " ^
+ CicMetaSubst.ppterm_in_context subst s context
+ (* "\nReason: " ^ Lazy.force e*)))) exn)
| exn ->
enrich localization_tbl hete
~f:(fun _ ->
fo_unif_l
test_equality_only subst metasenv (lr1, lr2) ugraph
with
- | UnificationFailure _ as exn ->
+ | UnificationFailure _
+ | Uncertain _ as exn ->
(match l1, l2 with
| (((Cic.Const (uri1, ens1)) as c1) :: tl1),
(((Cic.Const (uri2, ens2)) as c2) :: tl2) when
CoercGraph.is_a_coercion c2 ->
let body1, attrs1, ugraph =
match CicEnvironment.get_obj ugraph uri1 with
- | Cic.Constant (_,Some bo, _, _, attrs),u -> bo, attrs,u
+ | Cic.Constant (_,Some bo, _, _, attrs),u -> bo,attrs,u
| _ -> assert false
in
let body2, attrs2, ugraph =
with Invalid_argument _ ->
match t with
| Cic.Sort s -> Sort s
+ | Cic.Appl ((Cic.Const (uri, _))::_)
+ | Cic.Appl ((Cic.MutInd (uri, _, _))::_)
+ | Cic.Appl ((Cic.MutConstruct (uri, _, _, _))::_) -> Uri uri
| t -> Term t
;;
+let name_of_carr = function
+ | Uri u -> UriManager.name_of_uri u
+ | Sort s -> CicPp.ppsort s
+ | Term (Cic.Appl ((Cic.Const (uri, _))::_))
+ | Term (Cic.Appl ((Cic.MutInd (uri, _, _))::_))
+ | Term (Cic.Appl ((Cic.MutConstruct (uri, _, _, _))::_)) ->
+ UriManager.name_of_uri uri
+ | Term t -> (* CicPp.ppterm t *) assert false
+
let eq_carr src tgt =
match src, tgt with
| Uri src, Uri tgt -> UriManager.eq src tgt
else raise EqCarrOnNonMetaClosed
| _, _ -> false
-let name_of_carr = function
- | Uri u -> UriManager.name_of_uri u
- | Sort s -> CicPp.ppsort s
- | Term t -> CicPp.ppterm t
-
-
let to_list () =
!db
* *)
let coercion_hashtbl = UriManager.UriHashtbl.create 3
-let merge_coercions obj =
+let rec merge_coercions =
+ let module C = Cic in
+ let aux = (fun (u,t) -> u,merge_coercions t) in
+ function
+ C.Rel _ | C.Sort _ | C.Implicit _ as t -> t
+ | C.Meta (n,subst) ->
+ let subst' =
+ List.map
+ (function None -> None | Some t -> Some (merge_coercions t)) subst
+ in
+ C.Meta (n,subst')
+ | C.Cast (te,ty) -> C.Cast (merge_coercions te, merge_coercions ty)
+ | C.Prod (name,so,dest) ->
+ C.Prod (name, merge_coercions so, merge_coercions dest)
+ | C.Lambda (name,so,dest) ->
+ C.Lambda (name, merge_coercions so, merge_coercions dest)
+ | C.LetIn (name,so,dest) ->
+ C.LetIn (name, merge_coercions so, merge_coercions dest)
+ | Cic.Appl [ c1 ; (Cic.Appl [c2; head]) ] when
+ CoercGraph.is_a_coercion c1 && CoercGraph.is_a_coercion c2 ->
+ let source_carr = CoercGraph.source_of c2 in
+ let tgt_carr = CoercGraph.target_of c1 in
+ (match CoercGraph.look_for_coercion source_carr tgt_carr
+ with
+ | CoercGraph.SomeCoercion c -> Cic.Appl [ c ; head ]
+ | _ -> assert false) (* the composite coercion must exist *)
+ | C.Appl l -> C.Appl (List.map merge_coercions l)
+ | C.Var (uri,exp_named_subst) ->
+ let exp_named_subst = List.map aux exp_named_subst in
+ C.Var (uri, exp_named_subst)
+ | C.Const (uri,exp_named_subst) ->
+ let exp_named_subst = List.map aux exp_named_subst in
+ C.Const (uri, exp_named_subst)
+ | C.MutInd (uri,tyno,exp_named_subst) ->
+ let exp_named_subst = List.map aux exp_named_subst in
+ C.MutInd (uri,tyno,exp_named_subst)
+ | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
+ let exp_named_subst = List.map aux exp_named_subst in
+ C.MutConstruct (uri,tyno,consno,exp_named_subst)
+ | C.MutCase (uri,tyno,out,te,pl) ->
+ let pl = List.map merge_coercions pl in
+ C.MutCase (uri,tyno,merge_coercions out,merge_coercions te,pl)
+ | C.Fix (fno, fl) ->
+ let fl = List.map (fun (name,idx,ty,bo)->(name,idx,merge_coercions ty,merge_coercions bo)) fl in
+ C.Fix (fno, fl)
+ | C.CoFix (fno, fl) ->
+ let fl = List.map (fun (name,ty,bo) -> (name, merge_coercions ty, merge_coercions bo)) fl in
+ C.CoFix (fno, fl)
+
+let merge_coercions_in_obj obj =
let module C = Cic in
- let rec aux2 = (fun (u,t) -> u,aux t)
- and aux = function
- | C.Rel _ | C.Sort _ as t -> t
- | C.Meta _ | C.Implicit _ -> assert false
- | C.Cast (te,ty) -> C.Cast (aux te, aux ty)
- | C.Prod (name,so,dest) ->
- C.Prod (name, aux so, aux dest)
- | C.Lambda (name,so,dest) ->
- C.Lambda (name, aux so, aux dest)
- | C.LetIn (name,so,dest) ->
- C.LetIn (name, aux so, aux dest)
- | Cic.Appl [ c1 ; (Cic.Appl [c2; head]) ] when
- CoercGraph.is_a_coercion c1 && CoercGraph.is_a_coercion c2 ->
- let source_carr = CoercGraph.source_of c2 in
- let tgt_carr = CoercGraph.target_of c1 in
- (match CoercGraph.look_for_coercion source_carr tgt_carr
- with
- | CoercGraph.SomeCoercion c -> Cic.Appl [ c ; head ]
- | _ -> assert false) (* the composite coercion must exist *)
- | C.Appl l -> C.Appl (List.map aux l)
- | C.Var (uri,exp_named_subst) ->
- let exp_named_subst = List.map aux2 exp_named_subst in
- C.Var (uri, exp_named_subst)
- | C.Const (uri,exp_named_subst) ->
- let exp_named_subst = List.map aux2 exp_named_subst in
- C.Const (uri, exp_named_subst)
- | C.MutInd (uri,tyno,exp_named_subst) ->
- let exp_named_subst = List.map aux2 exp_named_subst in
- C.MutInd (uri,tyno,exp_named_subst)
- | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
- let exp_named_subst = List.map aux2 exp_named_subst in
- C.MutConstruct (uri,tyno,consno,exp_named_subst)
- | C.MutCase (uri,tyno,out,te,pl) ->
- let pl = List.map aux pl in
- C.MutCase (uri,tyno,aux out,aux te,pl)
- | C.Fix (fno, fl) ->
- let fl = List.map (fun (name,idx,ty,bo)->(name,idx,aux ty,aux bo)) fl in
- C.Fix (fno, fl)
- | C.CoFix (fno, fl) ->
- let fl = List.map (fun (name,ty,bo) -> (name, aux ty, aux bo)) fl in
- C.CoFix (fno, fl)
- in
match obj with
| C.Constant (id, body, ty, params, attrs) ->
let body =
match body with
| None -> None
- | Some body -> Some (aux body)
+ | Some body -> Some (merge_coercions body)
in
- let ty = aux ty in
+ let ty = merge_coercions ty in
C.Constant (id, body, ty, params, attrs)
| C.Variable (name, body, ty, params, attrs) ->
let body =
match body with
| None -> None
- | Some body -> Some (aux body)
+ | Some body -> Some (merge_coercions body)
in
- let ty = aux ty in
+ let ty = merge_coercions ty in
C.Variable (name, body, ty, params, attrs)
| C.CurrentProof (_name, _conjectures, _body, _ty, _params, _attrs) ->
assert false
let indtys =
List.map
(fun (name, ind, arity, cl) ->
- let arity = aux arity in
- let cl = List.map (fun (name, ty) -> (name,aux ty)) cl in
+ let arity = merge_coercions arity in
+ let cl = List.map (fun (name, ty) -> (name,merge_coercions ty)) cl in
(name, ind, arity, cl))
indtys
in
if (*List.mem `Generated (CicUtil.attributes_of_obj obj) &&*)
not (CoercGraph.is_a_coercion (Cic.Const (uri, [])))
then
- merge_coercions obj
+ merge_coercions_in_obj obj
else
obj
in
exception AlreadyDefined of UriManager.uri
+val merge_coercions: Cic.term -> Cic.term
+
(* adds an object to the library together with all auxiliary lemmas on it *)
(* (e.g. elimination principles, projections, etc.) *)
(* it returns the list of the uris of the auxiliary lemmas generated *)