File: ua_subalgebraT.v

package info (click to toggle)
coq-math-classes 9.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 1,120 kB
  • sloc: python: 22; makefile: 21; sh: 2
file content (82 lines) | stat: -rw-r--r-- 2,733 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(* This is an almost verbatim copy of ua_subalgebra, but with predicates in Type
instead of Prop (and with carrier sigT instead of sig).

Hopefully one day Coq's universe polymorphism will permit a merge of sig and sigT,
at which point we may try to merge ua_subalgebra and ua_subalgebraT as well. *)
Require Import
  Coq.Classes.RelationClasses
  MathClasses.interfaces.universal_algebra MathClasses.theory.ua_homomorphisms MathClasses.theory.categories MathClasses.interfaces.abstract_algebra.
Require
  MathClasses.categories.algebras.

Section subalgebras.
  Context `{Algebra sign A} (P: ∀ s, A s → Type).

  (* We begin by describing what it means for P to be a proper closed subset: *)

  Fixpoint op_closed {o: OpType (sorts sign)}: op_type A o → Type :=
    match o with
    | ne_list.one x => P x
    | ne_list.cons x y => λ d, ∀ z, P _ z → op_closed (d z)
    end.

  Definition op_closed_proper:
   ∀ (Pproper: ∀ s x x', x = x' → iffT (P s x) (P s x')) o,
   ∀ x x', x = x' → iffT (@op_closed o x) (@op_closed o x').
  Proof with intuition.
   induction o; simpl; intros x y E.
    intuition.
   split; intros...
    apply (IHo (x z))...
    apply E...
   apply (IHo (y z))...
   symmetry.
   apply E...
  Qed.

  Class ClosedSubset: Type :=
    { subset_proper: ∀ s x x', x = x' → iffT (P s x) (P s x')
    ; subset_closed: ∀ o, op_closed (algebra_op o) }.

  (* Now suppose P is closed in this way. *)

  Context `{ClosedSubset}.

  (* Our new algebra's elements are just those for which P holds: *)

  Definition carrier s := sigT (P s).

  Hint Extern 4 => progress unfold carrier: typeclass_instances.

  (* We can implement closed operations in the new algebra: *)

  Fixpoint close_op {d}: ∀ (o: op_type A d), op_closed o → op_type carrier d :=
    match d with
    | ne_list.one _ => λ o c, existT _ o (c)
    | ne_list.cons _ _ => λ o c X, close_op (o (projT1 X)) (c (projT1 X) (projT2 X))
    end.

  Global Instance impl: AlgebraOps sign carrier := λ o, close_op (algebra_op o) (subset_closed o).

  (* By showing that these ops are proper, we get our new algebra: *)
  Instance: ∀ d, Equiv (op_type carrier d).
   intro.
   apply op_type_equiv.
   intro.
   apply _.
  Defined.

  Definition close_op_proper d (o0 o1: op_type A d)
    (P': op_closed o0) (Q: op_closed o1): o0 = o1 → close_op o0 P' = close_op o1 Q.
  Proof with intuition.
   induction d; simpl in *...
   intros [x p] [y q] U.
   apply (IHd _ _ (P' x p) (Q y q)), H2...
  Qed.

  Global Instance subalgebra: Algebra sign carrier.
  Proof. constructor. apply _. intro. apply close_op_proper, algebra_propers. Qed.
End subalgebras.

#[global]
Hint Extern 4 => progress unfold carrier: typeclass_instances.