Skip to content

Commit f780650

Browse files
author
Will Bradley
committed
Parametrize Var by type
1 parent 679503c commit f780650

File tree

3 files changed

+55
-60
lines changed

3 files changed

+55
-60
lines changed

LogicFormalization/Chapter2/Section4/Homework.lean

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import Mathlib.Tactic.Ring
55

66
namespace Homeworks
77

8-
open Term HasVar
8+
universe u
9+
10+
open Term
911

1012
section Problem1
1113
/-! TODO -/
@@ -33,6 +35,8 @@ def 𝒩 : Structure .Rig ℕ where
3335
| .add, a => a 0 + a 1
3436
| .mul, a => a 0 * a 1
3537

38+
variable {V: Type u} [DecidableEq V]
39+
3640
section a
3741
variable (f: ℕ → ℕ)
3842
@[simp] abbrev isConstant := ∃ y, ∀ n, f n = y
@@ -76,7 +80,7 @@ lemma isConstant_or_isGe_of_mul:
7680

7781

7882
/-- 2.4 #5 (a) -/
79-
theorem not_exists_nat_rig_term₁ : ¬∃ (t: Term .Rig) (x: Var) (hx: AreVarsFor ![x] t),
83+
theorem not_exists_nat_rig_term₁ : ¬∃ (t: Term .Rig V) (x: V) (hx: AreVarsFor ![x] t),
8084
interp t 𝒩 hx ![0] = 1 ∧ interp t 𝒩 hx ![1] = 0 := by
8185
push_neg
8286
intro t x hx
@@ -229,7 +233,7 @@ where
229233
omega
230234

231235
/-- Convert one of the `L`-terms to a `Poly`. -/
232-
def ofTerm (t: Term .Rig) {x: Var} (hx: AreVarsFor ![x] t):
236+
def ofTerm (t: Term .Rig V) {x: V} (hx: AreVarsFor ![x] t):
233237
{ p // ∀ n, interp t 𝒩 hx ![n] = eval p n } :=
234238
match t with
235239
| .var _ => ⟨.var, fun n => by simp [interp, eval]⟩
@@ -248,7 +252,7 @@ end Poly
248252

249253

250254
/-- 2.4 #5 (b) -/
251-
theorem not_exists_nat_rig_term₂ : ¬∃ (t: Term .Rig) (x: Var) (hx: AreVarsFor ![x] t),
255+
theorem not_exists_nat_rig_term₂ : ¬∃ (t: Term .Rig V) (x: V) (hx: AreVarsFor ![x] t),
252256
∀ n, interp t 𝒩 hx ![n] = 2^n :=
253257
fun ⟨t, x, hx, h⟩ =>
254258
let ⟨p, hp⟩ := Poly.ofTerm t hx

LogicFormalization/Chapter2/Section4/Term.lean

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import LogicFormalization.Chapter2.Section3.Basic
22
import 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
2323
variable {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 VProp
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
5454
that we can easily talk about the index of a variable (see `idx`),
5555
which is used in `interp`. -/
5656

5757
/-- `AreVarsFor x t` means that `t = t(x₁, ..., xₘ)`, i.e. the `xᵢ` are
5858
unique 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
6868
then 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

9090
end AreVarsFor
9191

92-
variable {A: Type u} [Nonempty A]
92+
universe v
93+
variable {A: Type v} [Nonempty A]
9394

9495
open 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
105106
open Structure in
106107
/-- If `𝒜 ⊆ ℬ` are `L`-structures and `t` is an `L`-term with variables `x₁, ..., xₘ`,
107108
then 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
147148
interpretation 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`.
152153
See `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 =>
Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
11
import Mathlib.Data.Fintype.EquivFin
22
import Mathlib.Data.Real.Basic
33

4-
class HasVar.{u} where
5-
Var: Type u
6-
[emb: Function.Embedding ℕ Var]
7-
[decidable: DecidableEq Var]
4+
universe u
85

9-
export HasVar (Var)
6+
class Var (V: Type u) where
7+
var : ℕ ↪ V
108

11-
variable [HasVar]
9+
variable {V: Type u} [Var V]
1210

13-
def var (n: ℕ) : Var :=
14-
HasVar.emb n
11+
export Var (var)
1512

16-
lemma var_inj: ∀ {m n}, var m = var n → m = n :=
17-
@HasVar.emb.inj'
13+
lemma var_inj: ∀ {m n: ℕ}, var (V := V) m = var n → m = n :=
14+
@var.inj'
1815

19-
instance [HasVar] : DecidableEq Var :=
20-
HasVar.decidable
16+
abbrev v₀: V := var 0
17+
abbrev v₁: V := var 1
18+
abbrev v₂: V := var 2
19+
abbrev v₃: V := var 3
2120

22-
abbrev v₀ := var 0
23-
abbrev v₁ := var 1
24-
abbrev v₂ := var 2
25-
abbrev v₃ := var 3
21+
abbrev x: V := var 100
22+
abbrev y: V := var 101
23+
abbrev z: V := var 102
2624

27-
abbrev x := var 100
28-
abbrev y := var 101
29-
abbrev z := var 102
25+
instance : Var ℝ where
26+
var := ⟨(↑), CharZero.cast_injective⟩
3027

31-
namespace HasVar
32-
33-
noncomputable scoped instance (priority := low) instReal : HasVar where
34-
Var := ℝ
35-
emb := ⟨(↑), CharZero.cast_injective⟩
36-
37-
scoped instance (priority := high) instNat : HasVar where
38-
Var := ℕ
39-
emb := ⟨id, Function.injective_id⟩
28+
instance : Var ℕ where
29+
var := ⟨id, Function.injective_id⟩

0 commit comments

Comments
 (0)