11import LogicFormalization.Chapter2.Section3.Basic
22import LogicFormalization.Chapter2.Section4.Var
33
4- universe u v w
5- variable [HasVar]
4+ universe u
5+ variable {V: Type u}
66
7- inductive Term (L: Language)
7+ inductive Term (L: Language) (V: Type u := ULift ℕ)
88/-- `var v` represents the variable `v`, viewed as a word of length `1`-/
9- | var (v: Var )
9+ | var (v: V )
1010/-- `app F ts` represents the concatenation `Ft₁...tₙ`-/
11- | app (F: L.ϝ) (ts: Fin (arity F) → Term L)
11+ | app (F: L.ϝ) (ts: Fin (arity F) → Term L V )
1212
1313
14- example : Term Language.Ring :=
14+ example : Term Language.Ring ℕ :=
1515 .app .mul fun | 0 => .app .add fun
1616 | 0 => .var x
1717 | 1 => .app .neg fun
@@ -23,19 +23,19 @@ namespace Term
2323variable {L: Language}
2424
2525/-- Predicate for a variable occurring in a term. -/
26- def occursIn (v: Var ) : Term L → Prop
26+ def occursIn (v: V ) : Term L V → Prop
2727| .var v' => v = v'
2828| .app _ ts => ∃ i, occursIn v (ts i)
2929
30- lemma occursIn_app {v: Var } {F} {ts: Fin (arity F) → Term L}
30+ lemma occursIn_app {v: V } {F} {ts: Fin (arity F) → Term L V }
3131 {i} (h: occursIn v (ts i)): occursIn v (.app F ts) :=
3232 ⟨i, h⟩
3333
34- lemma occursIn_of_occursIn_app {v: Var } {F} {ts: Fin (arity F) → Term L}
34+ lemma occursIn_of_occursIn_app {v: V } {F} {ts: Fin (arity F) → Term L V }
3535 (h: occursIn v (.app F ts)): ∃ i, occursIn v (ts i) :=
3636 h
3737
38- instance instDecidableOccursIn (v ) (t: Term L) :
38+ instance instDecidableOccursIn [DecidableEq V] (v: V ) (t: Term L V ) :
3939 Decidable (occursIn v t) :=
4040 match t with
4141 | .var v' => if h: v = v' then .isTrue h else .isFalse h
@@ -50,13 +50,13 @@ instance instDecidableOccursIn (v) (t: Term L) :
5050 have := Fin.find_eq_none_iff.mp h
5151 .isFalse fun ⟨i, hi⟩ => this i hi
5252
53- /- N.B.: Here, we use an injective mapping from `Fin m` instead of a `Finset Var ` so
53+ /- N.B.: Here, we use an injective mapping from `Fin m` instead of a `Finset V ` so
5454that we can easily talk about the index of a variable (see `idx`),
5555which is used in `interp`. -/
5656
5757/-- `AreVarsFor x t` means that `t = t(x₁, ..., xₘ)`, i.e. the `xᵢ` are
5858unique and contain (possibly not strictly) all the variables in `t`. -/
59- structure AreVarsFor {m: ℕ} (x: Fin m → Var ) (t: Term L) where
59+ structure AreVarsFor {m: ℕ} (x: Fin m → V ) (t: Term L V ) where
6060 inj': Function.Injective x
6161 occursIn': ∀ {v}, occursIn v t → v ∈ Set.range x
6262
@@ -67,12 +67,12 @@ variable {t: Term L} {m: ℕ}
6767/-- If all the variables in a function application are in `x`, then
6868then the variables in each subterm remain in `x`. -/
6969@[simp]
70- lemma ofApp {F} {m} {ts: Fin (arity F) → Term L} {x: Fin m → Var } (hx: AreVarsFor x (app F ts)):
70+ lemma ofApp {F} {m} {ts: Fin (arity F) → Term L V } {x: Fin m → V } (hx: AreVarsFor x (app F ts)):
7171 (i: Fin (arity F)) → AreVarsFor x (ts i) :=
7272 fun _i => ⟨hx.inj', fun h => hx.occursIn' (occursIn_app h)⟩
7373
7474/-- The (unique) `index` of a variable `xᵢ` in a set `x₁, ..., xₘ` is just `i`. -/
75- def index {t: Term L} {v: Var } {x: Fin m → Var }
75+ def index [DecidableEq V] {t: Term L V } {v: V } {x: Fin m → V }
7676 (hx: AreVarsFor x t) (h: occursIn v t): { i : Fin m // x i = v } :=
7777 match t with
7878 | .var _v' =>
@@ -89,13 +89,14 @@ def index {t: Term L} {v: Var} {x: Fin m → Var}
8989
9090end AreVarsFor
9191
92- variable {A: Type u} [Nonempty A]
92+ universe v
93+ variable {A: Type v} [Nonempty A]
9394
9495open Structure
9596
9697/-- The interpretation `t^𝒜` of a term `t` with variables `x₁, ..., xₘ`
9798(which may not actually appear in `t`) is a function from `A^m` to `A`. -/
98- def interp (t: Term L) (𝒜: Structure L A) {m} {x: Fin m → Var } (hx: AreVarsFor x t):
99+ def interp [DecidableEq V] (t: Term L V ) (𝒜: Structure L A) {m} {x: Fin m → V } (hx: AreVarsFor x t):
99100 (Fin m → A) → A :=
100101 match t with
101102 | .var _xᵢ => fun as => as (hx.index rfl)
@@ -105,9 +106,9 @@ def interp (t: Term L) (𝒜: Structure L A) {m} {x: Fin m → Var} (hx: AreVars
105106open Structure in
106107/-- If `𝒜 ⊆ ℬ` are `L`-structures and `t` is an `L`-term with variables `x₁, ..., xₘ`,
107108then for all `a ∈ A^m`, `t^𝒜(a) = t^ℬ(a)`. -/
108- lemma interp_substructure {B: Type v} {A: Set B} [Nonempty A]
109+ lemma interp_substructure [DecidableEq V] {B: Type v} {A: Set B} [Nonempty A]
109110 {𝒜: Structure L A} {ℬ: Structure L B}
110- (h: 𝒜 ⊆ ℬ) {t: Term L} {m} {x: Fin m → Var } (hx: AreVarsFor x t):
111+ (h: 𝒜 ⊆ ℬ) {t: Term L V } {m} {x: Fin m → V } (hx: AreVarsFor x t):
111112 ∀ (a: Fin m → A), interp t 𝒜 hx a = interp t ℬ hx (a ·) :=
112113 match t with
113114 | .var v => fun a => rfl
@@ -119,12 +120,12 @@ lemma interp_substructure {B: Type v} {A: Set B} [Nonempty A]
119120 exact substructure_isSubstructure
120121
121122/-- "A term is said to be *variable-free* if no variables occur in it." -/
122- def varFree : Term L → Prop
123+ def varFree : Term L V → Prop
123124| .var _ => False
124125| .app _ ts => ∀ i, varFree (ts i)
125126
126127@[simp]
127- lemma not_varFree_var {v: Var }: ¬varFree (.var v: Term L) :=
128+ lemma not_varFree_var {v: V }: ¬varFree (.var v: Term L V ) :=
128129 False.elim
129130
130131@[simp]
@@ -133,30 +134,30 @@ lemma varFree_of_varFree_app {F} {ts: Fin (arity F) → Term L}
133134 @h
134135
135136@[simp]
136- lemma varFree_iff : ∀ {t: Term L}, varFree t ↔ ∀ v, ¬occursIn v t
137+ lemma varFree_iff : ∀ {t: Term L V }, varFree t ↔ ∀ v, ¬occursIn v t
137138| .var _ => by simp [varFree, occursIn]
138139| .app F ts => by
139140 simp only [varFree, occursIn, not_exists, varFree_iff]
140141 apply forall_comm
141142
142- def AreVarsFor.empty {t: Term L} (ht: varFree t): AreVarsFor Fin.elim0 t where
143+ def AreVarsFor.empty {t: Term L V } (ht: varFree t): AreVarsFor Fin.elim0 t where
143144 inj' := Function.injective_of_subsingleton _
144145 occursIn' := by simp [varFree_iff.mp ht _]
145146
146147/-- If `t` is variable-free, we can identify its
147148interpretation with a single value. -/
148- def interpConst (t: Term L) (ht: varFree t) (𝒜: Structure L A): A :=
149+ def interpConst [DecidableEq V] (t: Term L V ) (ht: varFree t) (𝒜: Structure L A): A :=
149150 interp t 𝒜 (.empty ht) Fin.elim0
150151
151152/-- The more natural way of expressing `interpConst`.
152153See `interpConst_eq_spec`. -/
153- def interpConst.spec (t: Term L) (ht: varFree t) (𝒜: Structure L A): A :=
154+ def interpConst.spec (t: Term L V ) (ht: varFree t) (𝒜: Structure L A): A :=
154155 match t with
155156 | .var _ => False.elim ht
156157 | .app F ts =>
157158 (F^𝒜) (fun i => spec (t := ts i) (ht i) 𝒜)
158159
159- lemma interpConst_eq_spec {t: Term L} (ht: varFree t) {𝒜: Structure L A} :
160+ lemma interpConst_eq_spec [DecidableEq V] {t: Term L V } (ht: varFree t) {𝒜: Structure L A} :
160161 interpConst t ht 𝒜 = interpConst.spec t ht 𝒜 :=
161162 match t with
162163 | .var _ => rfl
@@ -166,7 +167,7 @@ lemma interpConst_eq_spec {t: Term L} (ht: varFree t) {𝒜: Structure L A} :
166167 rfl
167168
168169/-- `replace t τ x` is `t(τ₁/x₁, ..., τₙ/xₙ)`. Note that `x` must be injective. -/
169- def replace (t: Term L) {m} (τ: Fin m → Term L) (x: Fin m ↪ Var ): Term L :=
170+ def replace [DecidableEq V] (t: Term L V ) {m} (τ: Fin m → Term L V ) (x: Fin m ↪ V ): Term L V :=
170171 match t with
171172 | .var v =>
172173 match Fin.find (fun j => x j = v) with
@@ -175,8 +176,8 @@ def replace (t: Term L) {m} (τ: Fin m → Term L) (x: Fin m ↪ Var): Term L :=
175176 | .app F ts => .app F (fun i => replace (ts i) τ x)
176177
177178/-- Lemma 2.4.1 -/
178- theorem replace_varFree {t: Term L} {m} {τ: Fin m → Term L}
179- {x: Fin m → Var } (hx: AreVarsFor x t) (h: ∀ i, varFree (τ i)):
179+ theorem replace_varFree [DecidableEq V] {t: Term L V } {m} {τ: Fin m → Term L V }
180+ {x: Fin m → V } (hx: AreVarsFor x t) (h: ∀ i, varFree (τ i)):
180181 varFree (replace t τ ⟨x, hx.inj'⟩) :=
181182 match t with
182183 | .var v =>
0 commit comments