Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 40bd947

Browse files
committed
feat(computability/primrec): add traditional primrec definition
This shows that the pairing function with its square roots does not give any additional power.
1 parent 5fea16e commit 40bd947

File tree

10 files changed

+602
-17
lines changed

10 files changed

+602
-17
lines changed

data/computability/primrec.lean

Lines changed: 388 additions & 2 deletions
Large diffs are not rendered by default.

data/encodable.lean

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,26 @@ def encode_subtype : {a : α // P a} → nat
267267

268268
include decP
269269
def decode_subtype (v : nat) : option {a : α // P a} :=
270-
match decode α v with
271-
| some a := if h : P a then some ⟨a, h⟩ else none
272-
| none := none
273-
end
270+
(decode α v).bind $ λ a,
271+
if h : P a then some ⟨a, h⟩ else none
274272

275273
instance subtype : encodable {a : α // P a} :=
276274
⟨encode_subtype, decode_subtype,
277275
λ ⟨v, h⟩, by simp [encode_subtype, decode_subtype, encodek, h]⟩
278276
end subtype
279277

278+
instance fin (n) : encodable (fin n) :=
279+
of_equiv _ (equiv.fin_equiv_subtype _)
280+
281+
instance vector [encodable α] {n} : encodable (vector α n) :=
282+
encodable.subtype
283+
284+
instance fin_arrow [encodable α] {n} : encodable (fin n → α) :=
285+
of_equiv _ (equiv.vector_equiv_fin _ _).symm
286+
287+
instance array [encodable α] {n} : encodable (array n α) :=
288+
of_equiv _ (equiv.array_equiv_fin _ _)
289+
280290
instance int : encodable ℤ :=
281291
of_equiv _ equiv.int_equiv_nat
282292

data/equiv.lean

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ We say two types are equivalent if they are isomorphic.
88
99
Two equivalent types have the same cardinality.
1010
-/
11-
import data.prod data.nat.pairing logic.function tactic data.set.lattice
12-
import algebra.group
11+
import data.prod data.nat.pairing logic.function tactic.basic
12+
import data.set.lattice algebra.group data.vector2
1313
open function
1414

1515
universes u v w
@@ -449,6 +449,21 @@ def list_equiv_of_equiv {α β : Type*} : α ≃ β → list α ≃ list β
449449
by refine ⟨list.map f, list.map g, λ x, _, λ x, _⟩;
450450
simp [id_of_left_inverse l, id_of_right_inverse r]
451451

452+
def fin_equiv_subtype (n : ℕ) : fin n ≃ {m // m < n} :=
453+
⟨λ x, ⟨x.1, x.2⟩, λ x, ⟨x.1, x.2⟩, λ ⟨a, b⟩, rfl,λ ⟨a, b⟩, rfl⟩
454+
455+
def vector_equiv_fin (α : Type*) (n : ℕ) : vector α n ≃ (fin n → α) :=
456+
⟨vector.nth, vector.of_fn, vector.of_fn_nth, λ f, funext $ vector.nth_of_fn f⟩
457+
458+
def d_array_equiv_fin (n : ℕ) (α : fin n → Type*) : d_array n α ≃ (Π i, α i) :=
459+
⟨d_array.read, d_array.mk, λ ⟨f⟩, rfl, λ f, rfl⟩
460+
461+
def array_equiv_fin (n : ℕ) (α : Type*) : array n α ≃ (fin n → α) :=
462+
d_array_equiv_fin _ _
463+
464+
def vector_equiv_array (α : Type*) (n : ℕ) : vector α n ≃ array n α :=
465+
(vector_equiv_fin _ _).trans (array_equiv_fin _ _).symm
466+
452467
def decidable_eq_of_equiv [h : decidable_eq α] : α ≃ β → decidable_eq β
453468
| ⟨f, g, l, r⟩ b₁ b₂ :=
454469
match h (g b₁) (g b₂) with

data/fin.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,18 @@ i.succ_rec H0 Hs
5151
{C : ∀ n, fin n → Sort*} {H0 Hs} {n} (i : fin n) :
5252
@fin.succ_rec_on (succ n) i.succ C H0 Hs = Hs n i (fin.succ_rec_on i H0 Hs) :=
5353
by cases i; refl
54+
55+
@[elab_as_eliminator] def fin.cases {n} {C : fin (succ n) → Sort*}
56+
(H0 : C 0) (Hs : ∀ i : fin n, C (i.succ)) :
57+
∀ (i : fin (succ n)), C i
58+
| ⟨0, h⟩ := H0
59+
| ⟨succ i, h⟩ := Hs ⟨i, lt_of_succ_lt_succ h⟩
60+
61+
@[simp] theorem fin.cases_zero
62+
{n} {C : fin (succ n) → Sort*} {H0 Hs} :
63+
@fin.cases n C H0 Hs 0 = H0 := rfl
64+
65+
@[simp] theorem fin.cases_succ
66+
{n} {C : fin (succ n) → Sort*} {H0 Hs} (i : fin n) :
67+
@fin.cases n C H0 Hs i.succ = Hs i :=
68+
by cases i; refl

data/list/basic.lean

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Basic properties of lists.
88
import tactic.interactive tactic.mk_iff_of_inductive_prop tactic.split_ifs
99
logic.basic logic.function
1010
algebra.group
11-
data.nat.basic data.option data.bool data.prod data.sigma
11+
data.nat.basic data.option data.bool data.prod data.sigma data.fin
1212
open function nat
1313

1414
namespace list
@@ -411,16 +411,23 @@ by subst l₁
411411

412412
/- head and tail -/
413413

414-
@[simp] theorem head_cons [h : inhabited α] (a : α) (l : list α) : head (a::l) = a := rfl
414+
@[simp] def head' : list α → option α
415+
| [] := none
416+
| (a :: l) := some a
417+
418+
theorem head_eq_head' [inhabited α] (l : list α) : head l = (head' l).iget :=
419+
by cases l; refl
420+
421+
@[simp] theorem head_cons [inhabited α] (a : α) (l : list α) : head (a::l) = a := rfl
415422

416423
@[simp] theorem tail_nil : tail (@nil α) = [] := rfl
417424

418425
@[simp] theorem tail_cons (a : α) (l : list α) : tail (a::l) = l := rfl
419426

420-
@[simp] theorem head_append [h : inhabited α] (t : list α) {s : list α} (h : s ≠ []) : head (s ++ t) = head s :=
427+
@[simp] theorem head_append [inhabited α] (t : list α) {s : list α} (h : s ≠ []) : head (s ++ t) = head s :=
421428
by {induction s, contradiction, simp}
422429

423-
theorem cons_head_tail [h : inhabited α] {l : list α} (h : l ≠ []) : (head l)::(tail l) = l :=
430+
theorem cons_head_tail [inhabited α] {l : list α} (h : l ≠ []) : (head l)::(tail l) = l :=
424431
by {induction l, contradiction, simp}
425432

426433
/- map -/
@@ -2289,6 +2296,69 @@ theorem length_sigma (l₁ : list α) (l₂ : Π a, list (σ a)) :
22892296
by induction l₁ with x l₁ IH; simp *
22902297
end
22912298

2299+
/- of_fn -/
2300+
def of_fn_aux {n} (f : fin n → α) : ∀ m, m ≤ n → list α → list α
2301+
| 0 h l := l
2302+
| (succ m) h l := of_fn_aux m (le_of_lt h) (f ⟨m, h⟩ :: l)
2303+
2304+
def of_fn {n} (f : fin n → α) : list α :=
2305+
of_fn_aux f n (le_refl _) []
2306+
2307+
theorem length_of_fn_aux {n} (f : fin n → α) :
2308+
∀ m h l, length (of_fn_aux f m h l) = length l + m
2309+
| 0 h l := rfl
2310+
| (succ m) h l := (length_of_fn_aux m _ _).trans (succ_add _ _)
2311+
2312+
theorem length_of_fn {n} (f : fin n → α) : length (of_fn f) = n :=
2313+
(length_of_fn_aux f _ _ _).trans (zero_add _)
2314+
2315+
def of_fn_nth_val {n} (f : fin n → α) (i : ℕ) : option α :=
2316+
if h : _ then some (f ⟨i, h⟩) else none
2317+
2318+
theorem nth_of_fn_aux {n} (f : fin n → α) (i) :
2319+
∀ m h l,
2320+
(∀ i, nth l i = of_fn_nth_val f (i + m)) →
2321+
nth (of_fn_aux f m h l) i = of_fn_nth_val f i
2322+
| 0 h l H := H i
2323+
| (succ m) h l H := nth_of_fn_aux m _ _ begin
2324+
intro j, cases j with j,
2325+
{ simp [of_fn_nth_val, show m < n, from h], refl },
2326+
{ simp [H, succ_add, -add_comm] }
2327+
end
2328+
2329+
@[simp] theorem nth_of_fn {n} (f : fin n → α) (i) :
2330+
nth (of_fn f) i = of_fn_nth_val f i :=
2331+
nth_of_fn_aux f _ _ _ _ $ λ i,
2332+
by simp [of_fn_nth_val, not_lt.2 (le_add_right n i)]
2333+
2334+
theorem nth_le_of_fn {n} (f : fin n → α) (i : fin n) :
2335+
nth_le (of_fn f) i.1 ((length_of_fn f).symm ▸ i.2) = f i :=
2336+
option.some.inj $ by rw [← nth_le_nth];
2337+
simp [of_fn_nth_val, i.2]; cases i; refl
2338+
2339+
theorem array_eq_of_fn {n} (a : array n α) : a.to_list = of_fn a.read :=
2340+
suffices ∀ {m h l}, d_array.rev_iterate_aux a
2341+
(λ i, cons) m h l = of_fn_aux (d_array.read a) m h l, from this,
2342+
begin
2343+
intros, induction m with m IH generalizing l, {refl},
2344+
simp [d_array.rev_iterate_aux, of_fn_aux, IH]
2345+
end
2346+
2347+
theorem of_fn_zero (f : fin 0 → α) : of_fn f = [] := rfl
2348+
2349+
theorem of_fn_succ {n} (f : fin (succ n) → α) :
2350+
of_fn f = f 0 :: of_fn (λ i, f i.succ) :=
2351+
suffices ∀ {m h l}, of_fn_aux f (succ m) (succ_le_succ h) l =
2352+
f 0 :: of_fn_aux (λ i, f i.succ) m h l, from this,
2353+
begin
2354+
intros, induction m with m IH generalizing l, {refl},
2355+
rw [of_fn_aux, IH], refl
2356+
end
2357+
2358+
theorem of_fn_nth_le : ∀ l : list α, of_fn (λ i, nth_le l i.1 i.2) = l
2359+
| [] := rfl
2360+
| (a::l) := by rw of_fn_succ; congr; simp; exact of_fn_nth_le l
2361+
22922362
/- disjoint -/
22932363
section disjoint
22942364

data/nat/sqrt.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ theorem sqrt_eq_zero {n : ℕ} : sqrt n = 0 ↔ n = 0 :=
150150
by rw [h]; exact dec_trivial,
151151
λ e, e.symm ▸ rfl⟩
152152

153+
theorem eq_sqrt {n q} : q = sqrt n ↔ q*q ≤ n ∧ n < (q+1)*(q+1) :=
154+
⟨λ e, e.symm ▸ sqrt_is_sqrt n,
155+
λ ⟨h₁, h₂⟩, le_antisymm (le_sqrt.2 h₁) (le_of_lt_succ $ sqrt_lt.2 h₂)⟩
156+
153157
theorem le_three_of_sqrt_eq_one {n : ℕ} (h : sqrt n = 1) : n ≤ 3 :=
154158
le_of_lt_succ $ (@sqrt_lt n 2).1 $
155159
by rw [h]; exact dec_trivial
@@ -170,4 +174,10 @@ le_antisymm
170174
theorem sqrt_eq (n : ℕ) : sqrt (n*n) = n :=
171175
sqrt_add_eq n (zero_le _)
172176

177+
theorem sqrt_succ_le_succ_sqrt (n : ℕ) : sqrt n.succ ≤ n.sqrt.succ :=
178+
le_of_lt_succ $ sqrt_lt.2 $ lt_succ_of_le $ succ_le_succ $
179+
le_trans (sqrt_le_add n) $ add_le_add_right
180+
(by refine add_le_add
181+
(mul_le_mul_right _ _) _; exact le_add_right _ 2) _
182+
173183
end nat

data/set/basic.lean

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,7 @@ theorem image_union (f : α → β) (s t : set α) :
687687
f '' (s ∪ t) = f '' s ∪ f '' t :=
688688
by finish [set_eq_def, iff_def, mem_image_eq]
689689

690-
@[simp] theorem image_empty (f : α → β) : f '' ∅ = ∅ :=
691-
by finish [set_eq_def, mem_image_eq]
690+
@[simp] theorem image_empty (f : α → β) : f '' ∅ = ∅ := ext $ by simp
692691

693692
theorem image_inter_on {f : α → β} {s t : set α} (h : ∀x∈t, ∀y∈s, f x = f y → x = y) :
694693
f '' s ∩ f '' t = f '' (s ∩ t) :=
@@ -718,8 +717,7 @@ begin
718717
intro x, split; { intro e, subst e, simp }
719718
end
720719

721-
theorem image_id (s : set α) : id '' s = s :=
722-
by finish [set_eq_def, iff_def, mem_image_eq]
720+
@[simp] theorem image_id (s : set α) : id '' s = s := ext $ by simp
723721

724722
theorem compl_compl_image (S : set (set α)) :
725723
compl '' (compl '' S) = S :=

data/sigma/basic.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ end psigma
7272
section subtype
7373
variables {α : Sort*} {β : α → Prop}
7474

75+
protected lemma subtype.eq' : ∀ {a1 a2 : {x // β x}}, a1.val = a2.val → a1 = a2
76+
| ⟨x, h1⟩ ⟨.(x), h2⟩ rfl := rfl
77+
78+
lemma subtype.ext {a1 a2 : {x // β x}} : a1 = a2 ↔ a1.val = a2.val :=
79+
⟨congr_arg _, subtype.eq'⟩
80+
81+
theorem subtype.val_injective : function.injective (@subtype.val _ β) :=
82+
λ a b, subtype.eq'
83+
7584
@[simp] theorem subtype.coe_eta {α : Type*} {β : α → Prop}
7685
(a : {a // β a}) (h : β a) : subtype.mk ↑a h = a := subtype.eta _ _
7786

data/vector2.lean

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/-
2+
Copyright (c) 2018 Mario Carneiro. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mario Carneiro
5+
6+
Additional theorems about the `vector` type.
7+
-/
8+
import data.vector data.list.basic data.sigma
9+
10+
namespace vector
11+
variables {α : Type*} {n : ℕ}
12+
13+
attribute [simp] head_cons tail_cons
14+
15+
instance [inhabited α] : inhabited (vector α n) :=
16+
⟨of_fn (λ _, default α)⟩
17+
18+
theorem to_list_injective : function.injective (@to_list α n) :=
19+
subtype.val_injective
20+
21+
@[simp] theorem to_list_of_fn : ∀ {n} (f : fin n → α), to_list (of_fn f) = list.of_fn f
22+
| 0 f := rfl
23+
| (n+1) f := by rw [of_fn, list.of_fn_succ, to_list_cons, to_list_of_fn]
24+
25+
theorem mk_to_list :
26+
∀ (v : vector α n) h, (⟨to_list v, h⟩ : vector α n) = v
27+
| ⟨l, h₁⟩ h₂ := rfl
28+
29+
theorem nth_eq_nth_le : ∀ (v : vector α n) (i),
30+
nth v i = v.to_list.nth_le i.1 (by rw to_list_length; exact i.2)
31+
| ⟨l, h⟩ i := rfl
32+
33+
@[simp] theorem nth_of_fn {n} (f : fin n → α) (i) : nth (of_fn f) i = f i :=
34+
by rw [nth_eq_nth_le, ← list.nth_le_of_fn f];
35+
congr; apply to_list_of_fn
36+
37+
@[simp] theorem of_fn_nth (v : vector α n) : of_fn (nth v) = v :=
38+
begin
39+
rcases v with ⟨l, rfl⟩,
40+
apply to_list_injective,
41+
change nth ⟨l, eq.refl _⟩ with λ i, nth ⟨l, rfl⟩ i,
42+
simp [nth, list.of_fn_nth_le]
43+
end
44+
45+
@[simp] theorem nth_tail : ∀ (v : vector α n.succ) (i : fin n),
46+
nth (tail v) i = nth v i.succ
47+
| ⟨a::l, e⟩ ⟨i, h⟩ := by simp [nth_eq_nth_le]; refl
48+
49+
@[simp] theorem tail_of_fn {n : ℕ} (f : fin n.succ → α) :
50+
tail (of_fn f) = of_fn (λ i, f i.succ) :=
51+
(of_fn_nth _).symm.trans $ by congr; funext i; simp
52+
53+
theorem head'_to_list : ∀ (v : vector α n.succ),
54+
(to_list v).head' = some (head v)
55+
| ⟨a::l, e⟩ := rfl
56+
57+
@[simp] theorem nth_zero : ∀ (v : vector α n.succ), nth v 0 = head v
58+
| ⟨a::l, e⟩ := rfl
59+
60+
@[simp] theorem head_of_fn
61+
{n : ℕ} (f : fin n.succ → α) : head (of_fn f) = f 0 :=
62+
by rw [← nth_zero, nth_of_fn]
63+
64+
@[simp] theorem nth_cons_zero
65+
(a : α) (v : vector α n) : nth (a :: v) 0 = a :=
66+
by simp [nth_zero]
67+
68+
@[simp] theorem nth_cons_succ
69+
(a : α) (v : vector α n) (i : fin n) : nth (a :: v) i.succ = nth v i :=
70+
by rw [← nth_tail, tail_cons]
71+
72+
end vector

logic/embedding.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected def of_not_nonempty {α : Sort u} {β : Sort v} (hα : ¬ nonempty α)
6565
⟨λa, (hα ⟨a⟩).elim, assume a, (hα ⟨a⟩).elim⟩
6666

6767
def subtype {α} (p : α → Prop) : subtype p ↪ α :=
68-
⟨subtype.val, λ a b, subtype.eq⟩
68+
⟨subtype.val, λ _ _, subtype.eq'
6969

7070
/-- Restrict the codomain of an embedding. -/
7171
def cod_restrict {α β} (p : set β) (f : α ↪ β) (H : ∀ a, f a ∈ p) : α ↪ p :=

0 commit comments

Comments
 (0)