summaryrefslogtreecommitdiff
path: root/Algebra/Derivations.lean
blob: 6f81e9a88f230a63d9a7e5acdcff03539fde93b9 (plain)
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import Mathlib
import Algebra.Terms

namespace Algebra

section Theories

variable (𝔸 : Type) [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸]
variable (sig : Signature)

structure Equation where
  vars : Type
  [vars_nominal : NominalSet 𝔸 vars]
  [vars_orbitFinite : OrbitFinite 𝔸 vars]
  left : Term 𝔸 sig vars
  right : Term 𝔸 sig vars

namespace Equation

instance (eq : Equation 𝔸 sig) : NominalSet 𝔸 eq.vars :=
  eq.vars_nominal

instance (eq : Equation 𝔸 sig) : OrbitFinite 𝔸 eq.vars :=
  eq.vars_orbitFinite

def HasDepth
    {𝔸 : Type} [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸] {sig : Signature}
    (eq : Equation 𝔸 sig) (n : β„•) : Prop :=
  eq.left.HasDepth n ∧ eq.right.HasDepth n

end Equation

def EquationAtDepth (n : β„•) :=
  { eq : Equation 𝔸 sig // eq.HasDepth n }

def UniformEquation :=
  { eq : Equation 𝔸 sig // βˆƒ n, eq.HasDepth n }

structure Theory where
  sig : Signature
  axioms : Set (UniformEquation 𝔸 sig)

end Theories

variable {𝔸 : Type} [Infinite 𝔸] [Countable 𝔸] [DecidableEq 𝔸]
variable {sig : Signature}

section Helpers

def EquationAtDepth.left {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : TermAtDepth 𝔸 sig eq.val.vars n :=
  ⟨eq.val.left, eq.prop.left⟩

def EquationAtDepth.right {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : TermAtDepth 𝔸 sig eq.val.vars n :=
  ⟨eq.val.right, eq.prop.right⟩

def EquationAtDepth.mk
    (X : Type) [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] {n : β„•} (t u : TermAtDepth 𝔸 sig X n) :
    EquationAtDepth 𝔸 sig n :=
  ⟨⟨X, t.val, u.val⟩, ⟨t.prop, u.prop⟩⟩

def EquationAtDepth.toUniform {n : β„•} (eq : EquationAtDepth 𝔸 sig n) : UniformEquation 𝔸 sig :=
  ⟨eq.val, ⟨n, eq.prop⟩⟩

notation:50 X " ⊒ " lhs " ≣ " rhs => EquationAtDepth.mk X lhs rhs

end Helpers

section DerivableEquations

inductive Derivable (T : Theory 𝔸) : {m : β„•} β†’ (eq : EquationAtDepth 𝔸 T.sig m) β†’ Prop
  | refl {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] {x : X} :
      Derivable T (X ⊒ .var x ≣ .var x)
  | symm {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {m : β„•} {t u : TermAtDepth 𝔸 T.sig X m} :
      Derivable T (X ⊒ u ≣ t) β†’
      Derivable T (X ⊒ t ≣ u)
  | trans {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {m : β„•} {t u v : TermAtDepth 𝔸 T.sig X m} :
      Derivable T (X ⊒ t ≣ v) β†’
      Derivable T (X ⊒ v ≣ u) β†’
      Derivable T (X ⊒ t ≣ u)
  | cong_pure {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {f : T.sig.pure} {m : β„•} {ts us : T.sig.pureArgs f β†’ TermAtDepth 𝔸 T.sig X m} :
      (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’
      Derivable T (X ⊒ .pure f ts ≣ .pure f us)
  | cong_free {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {a : 𝔸} {f : T.sig.free} {m : β„•} {ts us : T.sig.freeArgs f β†’ TermAtDepth 𝔸 T.sig X m} :
      (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’
      Derivable T (X ⊒ .free a f ts ≣ .free a f us)
  | cong_bound {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {a : 𝔸} {f : T.sig.bound} {m : β„•} {ts us : T.sig.boundArgs f β†’ TermAtDepth 𝔸 T.sig X m} :
      (βˆ€ x, Derivable T (X ⊒ ts x ≣ us x)) β†’
      Derivable T (X ⊒ .bound a f ts ≣ .bound a f us)
  | ax' {X Y : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] [NominalSet 𝔸 Y] [OrbitFinite 𝔸 Y]
      {m : β„•} {r s : TermAtDepth 𝔸 T.sig Y m}
      {l : β„•} {Οƒ : UniformSubstitution 𝔸 T.sig Y X l} {Ο„ : FPerm 𝔸} :
      ((Y ⊒ r ≣ s).toUniform ∈ T.axioms) β†’
      (βˆ€ (y : Y) (Ο€ : FPerm 𝔸), Derivable T (X ⊒ Οƒ (Ο€ β€’ y) ≣ Ο€ β€’ (Οƒ y))) β†’
      Derivable T (X ⊒ Οƒ.apply (Ο„ β€’ r) ≣ Οƒ.apply (Ο„ β€’ s))
  | perm {X : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X]
      {a b : 𝔸} {f : T.sig.bound} {m : β„•} {ts us : T.sig.boundArgs f β†’ TermAtDepth 𝔸 T.sig X m} :
      a β‰  b β†’
      (βˆ€ x, a # us x) β†’
      (βˆ€ x, Derivable T (X ⊒ ts x ≣ βΈ¨a, bβΈ© β€’ us x)) β†’
      Derivable T (X ⊒ .bound a f ts ≣ .bound b f us)

variable {X Y : Type} [NominalSet 𝔸 X] [OrbitFinite 𝔸 X] [NominalSet 𝔸 Y] [OrbitFinite 𝔸 Y]

def UniformSubstitution.DerivablyEquivariant
    (T : Theory 𝔸) {l : β„•} (Οƒ : UniformSubstitution 𝔸 T.sig X Y l) : Prop :=
  (βˆ€ (x : X) (Ο€ : FPerm 𝔸), Derivable T (Y ⊒ Οƒ (Ο€ β€’ x) ≣ Ο€ β€’ Οƒ x))

/-- Restated ax' rule using DerivablyEquivariant in the premiss. -/
lemma Derivable.ax
    {T : Theory 𝔸}
    {m : β„•} {r s : TermAtDepth 𝔸 T.sig Y m}
    {l : β„•} {Οƒ : UniformSubstitution 𝔸 T.sig Y X l} {Ο„ : FPerm 𝔸} :
    ((Y ⊒ r ≣ s).toUniform ∈ T.axioms) β†’
    Οƒ.DerivablyEquivariant T β†’
    Derivable T (X ⊒ Οƒ.apply (Ο„ β€’ r) ≣ Οƒ.apply (Ο„ β€’ s)) :=
  .ax'

lemma Derivable.equivariant_substitution
    (T : Theory 𝔸)
    {l : β„•} (Οƒ : UniformSubstitution 𝔸 T.sig Y X l) (hequi : Οƒ.DerivablyEquivariant T)
    {m : β„•} (t : TermAtDepth 𝔸 T.sig Y m) {Ο€ : FPerm 𝔸} :
    Derivable T (X ⊒ Οƒ.apply (Ο€ β€’ t) ≣ Ο€ β€’ (Οƒ.apply t)) := by
  induction' t using TermAtDepth.induction <;> expose_names
  Β· sorry
  Β· sorry
  Β· sorry
  Β· sorry

end DerivableEquations

end Algebra