@@ -330,18 +330,17 @@ end Primrec
330
330
def Primrec₂ {α β σ} [Primcodable α] [Primcodable β] [Primcodable σ] (f : α → β → σ) :=
331
331
Primrec fun p : α × β => f p.1 p.2
332
332
333
- /-- `PrimrecPred p` means `p : α → Prop` is a (decidable)
333
+ /-- `PrimrecPred p` means `p : α → Prop` is a
334
334
primitive recursive predicate, which is to say that
335
335
`decide ∘ p : α → Bool` is primitive recursive. -/
336
- def PrimrecPred {α} [Primcodable α] (p : α → Prop ) [DecidablePred p] :=
337
- Primrec fun a => decide (p a)
336
+ def PrimrecPred {α} [Primcodable α] (p : α → Prop ) :=
337
+ ∃ (_ : DecidablePred p), Primrec fun a => decide (p a)
338
338
339
- /-- `PrimrecRel p` means `p : α → β → Prop` is a (decidable)
339
+ /-- `PrimrecRel p` means `p : α → β → Prop` is a
340
340
primitive recursive relation, which is to say that
341
341
`decide ∘ p : α → β → Bool` is primitive recursive. -/
342
- def PrimrecRel {α β} [Primcodable α] [Primcodable β] (s : α → β → Prop )
343
- [∀ a b, Decidable (s a b)] :=
344
- Primrec₂ fun a b => decide (s a b)
342
+ def PrimrecRel {α β} [Primcodable α] [Primcodable β] (s : α → β → Prop ) :=
343
+ PrimrecPred fun p : α × β => s p.1 p.2
345
344
346
345
namespace Primrec₂
347
346
@@ -408,29 +407,53 @@ theorem Primrec₂.comp₂ {f : γ → δ → σ} {g : α → β → γ} {h : α
408
407
(hg : Primrec₂ g) (hh : Primrec₂ h) : Primrec₂ fun a b => f (g a b) (h a b) :=
409
408
hf.comp hg hh
410
409
411
- theorem PrimrecPred.comp {p : β → Prop } [DecidablePred p] {f : α → β} :
412
- PrimrecPred p → Primrec f → PrimrecPred fun a => p (f a) :=
413
- Primrec.comp
410
+ protected lemma PrimrecPred.decide {p : α → Prop } [DecidablePred p] (hp : PrimrecPred p) :
411
+ Primrec ( fun a => decide (p a)) := by
412
+ convert hp.choose_spec
414
413
415
- theorem PrimrecRel.comp {R : β → γ → Prop } [∀ a b, Decidable (R a b)] {f : α → β} {g : α → γ} :
416
- PrimrecRel R → Primrec f → Primrec g → PrimrecPred fun a => R (f a) (g a) :=
417
- Primrec₂.comp
414
+ lemma Primrec.primrecPred {p : α → Prop } [DecidablePred p]
415
+ (hp : Primrec ( fun a => decide (p a))) : PrimrecPred p :=
416
+ ⟨inferInstance, hp⟩
418
417
419
- theorem PrimrecRel.comp₂ {R : γ → δ → Prop } [∀ a b, Decidable (R a b)] {f : α → β → γ}
420
- {g : α → β → δ} :
418
+ lemma primrecPred_iff_primrec_decide {p : α → Prop } [DecidablePred p] :
419
+ PrimrecPred p ↔ Primrec (fun a => decide (p a)) where
420
+ mp := PrimrecPred.decide
421
+ mpr := Primrec.primrecPred
422
+
423
+ theorem PrimrecPred.comp {p : β → Prop } {f : α → β} :
424
+ (hp : PrimrecPred p) → (hf : Primrec f) → PrimrecPred fun a => p (f a)
425
+ | ⟨_i, hp⟩, hf => hp.comp hf |>.primrecPred
426
+
427
+ protected lemma PrimrecRel.decide {R : α → β → Prop } [DecidableRel R] (hR : PrimrecRel R) :
428
+ Primrec₂ (fun a b => decide (R a b)) :=
429
+ PrimrecPred.decide hR
430
+
431
+ lemma Primrec₂.primrecRel {R : α → β → Prop } [DecidableRel R]
432
+ (hp : Primrec₂ (fun a b => decide (R a b))) : PrimrecRel R :=
433
+ Primrec.primrecPred hp
434
+
435
+ lemma primrecRel_iff_primrec_decide {R : α → β → Prop } [DecidableRel R] :
436
+ PrimrecRel R ↔ Primrec₂ (fun a b => decide (R a b)) where
437
+ mp := PrimrecRel.decide
438
+ mpr := Primrec₂.primrecRel
439
+
440
+ theorem PrimrecRel.comp {R : β → γ → Prop } {f : α → β} {g : α → γ}
441
+ (hR : PrimrecRel R) (hf : Primrec f) (hg : Primrec g) : PrimrecPred fun a => R (f a) (g a) :=
442
+ PrimrecPred.comp hR (hf.pair hg)
443
+
444
+ theorem PrimrecRel.comp₂ {R : γ → δ → Prop } {f : α → β → γ} {g : α → β → δ} :
421
445
PrimrecRel R → Primrec₂ f → Primrec₂ g → PrimrecRel fun a b => R (f a b) (g a b) :=
422
446
PrimrecRel.comp
423
447
424
448
end Comp
425
449
426
- theorem PrimrecPred.of_eq {α} [Primcodable α] {p q : α → Prop } [DecidablePred p] [DecidablePred q]
450
+ theorem PrimrecPred.of_eq {α} [Primcodable α] {p q : α → Prop }
427
451
(hp : PrimrecPred p) (H : ∀ a, p a ↔ q a) : PrimrecPred q :=
428
- Primrec.of_eq hp fun a => Bool.decide_congr (H a)
452
+ funext ( fun a => propext (H a)) ▸ hp
429
453
430
454
theorem PrimrecRel.of_eq {α β} [Primcodable α] [Primcodable β] {r s : α → β → Prop }
431
- [∀ a b, Decidable (r a b)] [∀ a b, Decidable (s a b)] (hr : PrimrecRel r)
432
- (H : ∀ a b, r a b ↔ s a b) : PrimrecRel s :=
433
- Primrec₂.of_eq hr fun a b => Bool.decide_congr (H a b)
455
+ (hr : PrimrecRel r) (H : ∀ a b, r a b ↔ s a b) : PrimrecRel s :=
456
+ funext₂ (fun a b => propext (H a b)) ▸ hr
434
457
435
458
namespace Primrec₂
436
459
@@ -439,7 +462,11 @@ variable [Primcodable α] [Primcodable β] [Primcodable σ]
439
462
440
463
open Nat.Primrec
441
464
442
- theorem swap {f : α → β → σ} (h : Primrec₂ f) : Primrec₂ (swap f) :=
465
+ protected theorem swap {f : α → β → σ} (h : Primrec₂ f) : Primrec₂ (swap f) :=
466
+ h.comp₂ Primrec₂.right Primrec₂.left
467
+
468
+ protected theorem _root_.PrimrecRel.swap {r : α → β → Prop } (h : PrimrecRel r) :
469
+ PrimrecRel (swap r) :=
443
470
h.comp₂ Primrec₂.right Primrec₂.left
444
471
445
472
theorem nat_iff {f : α → β → σ} : Primrec₂ f ↔ Nat.Primrec
@@ -465,7 +492,11 @@ variable {α : Type*} {β : Type*} {σ : Type*}
465
492
variable [Primcodable α] [Primcodable β] [Primcodable σ]
466
493
467
494
theorem to₂ {f : α × β → σ} (hf : Primrec f) : Primrec₂ fun a b => f (a, b) :=
468
- hf.of_eq fun _ => rfl
495
+ hf
496
+
497
+ lemma _root_.PrimrecPred.primrecRel {p : α × β → Prop } (hp : PrimrecPred p) :
498
+ PrimrecRel fun a b => p (a, b) :=
499
+ hp
469
500
470
501
theorem nat_rec {f : α → β} {g : α → ℕ × β → β} (hf : Primrec f) (hg : Primrec₂ g) :
471
502
Primrec₂ fun a (n : ℕ) => n.rec (motive := fun _ => β) (f a) fun n IH => g a (n, IH) :=
@@ -571,14 +602,14 @@ theorem cond {c : α → Bool} {f : α → σ} {g : α → σ} (hc : Primrec c)
571
602
572
603
theorem ite {c : α → Prop } [DecidablePred c] {f : α → σ} {g : α → σ} (hc : PrimrecPred c)
573
604
(hf : Primrec f) (hg : Primrec g) : Primrec fun a => if c a then f a else g a := by
574
- simpa [Bool.cond_decide] using cond hc hf hg
605
+ simpa [Bool.cond_decide] using cond hc.decide hf hg
575
606
576
607
theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop ) :=
577
- (nat_casesOn nat_sub (const true ) (const false ).to₂).of_eq fun p => by
608
+ Primrec₂.primrecRel ( (nat_casesOn nat_sub (const true ) (const false ).to₂).of_eq fun p => by
578
609
dsimp [swap]
579
610
rcases e : p.1 - p.2 with - | n
580
611
· simp [Nat.sub_eq_zero_iff_le.1 e]
581
- · simp [not_le.2 (Nat.lt_of_sub_eq_succ e)]
612
+ · simp [not_le.2 (Nat.lt_of_sub_eq_succ e)])
582
613
583
614
theorem nat_min : Primrec₂ (@min ℕ _) :=
584
615
ite nat_le fst snd
@@ -602,30 +633,31 @@ protected theorem and : Primrec₂ and :=
602
633
protected theorem or : Primrec₂ or :=
603
634
dom_bool₂ _
604
635
605
- theorem _root_.PrimrecPred.not {p : α → Prop } [DecidablePred p] (hp : PrimrecPred p) :
606
- PrimrecPred fun a => ¬p a :=
607
- ( Primrec.not.comp hp) .of_eq fun n => by simp
636
+ protected theorem _root_.PrimrecPred.not {p : α → Prop } :
637
+ (hp : PrimrecPred p) → PrimrecPred fun a => ¬p a
638
+ | ⟨_, hp⟩ => Primrec.primrecPred <| Primrec. not.comp hp |> .of_eq <| by simp
608
639
609
- theorem _root_.PrimrecPred.and {p q : α → Prop } [DecidablePred p] [DecidablePred q]
610
- (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∧ q a :=
611
- ( Primrec.and.comp hp hq) .of_eq fun n => by simp
640
+ protected theorem _root_.PrimrecPred.and {p q : α → Prop } :
641
+ (hp : PrimrecPred p) → (hq : PrimrecPred q) → PrimrecPred fun a => p a ∧ q a
642
+ | ⟨_, hp⟩, ⟨_, hq⟩ => Primrec.primrecPred <| Primrec. and.comp hp hq |> .of_eq <| by simp
612
643
613
- theorem _root_.PrimrecPred.or {p q : α → Prop } [DecidablePred p] [DecidablePred q]
614
- (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∨ q a :=
615
- ( Primrec.or.comp hp hq) .of_eq fun n => by simp
644
+ protected theorem _root_.PrimrecPred.or {p q : α → Prop } :
645
+ (hp : PrimrecPred p) → (hq : PrimrecPred q) → PrimrecPred fun a => p a ∨ q a
646
+ | ⟨_, hp⟩, ⟨_, hq⟩ => Primrec.primrecPred <| Primrec. or.comp hp hq |> .of_eq <| by simp
616
647
617
- protected theorem beq [DecidableEq α] : Primrec₂ (@BEq.beq α _ ) :=
648
+ protected theorem eq : PrimrecRel (@Eq α ) :=
618
649
have : PrimrecRel fun a b : ℕ => a = b :=
619
650
(PrimrecPred.and nat_le nat_le.swap).of_eq fun a => by simp [le_antisymm_iff]
620
- (this.comp₂ (Primrec.encode.comp₂ Primrec₂.left) (Primrec.encode.comp₂ Primrec₂.right)).of_eq
651
+ (this.decide.comp₂ (Primrec.encode.comp₂ Primrec₂.left)
652
+ (Primrec.encode.comp₂ Primrec₂.right)).primrecRel.of_eq
621
653
fun _ _ => encode_injective.eq_iff
622
654
623
- protected theorem eq [DecidableEq α] : PrimrecRel (@Eq α ) := Primrec.beq
655
+ protected theorem beq [DecidableEq α] : Primrec₂ (@BEq.beq α _ ) := Primrec.eq.decide
624
656
625
657
theorem nat_lt : PrimrecRel ((· < ·) : ℕ → ℕ → Prop ) :=
626
658
(nat_le.comp snd fst).not.of_eq fun p => by simp
627
659
628
- theorem option_guard {p : α → β → Prop } [∀ a b, Decidable (p a b) ] (hp : PrimrecRel p) {f : α → β}
660
+ theorem option_guard {p : α → β → Prop } [DecidableRel p ] (hp : PrimrecRel p) {f : α → β}
629
661
(hf : Primrec f) : Primrec fun a => Option.guard (p a) (f a) :=
630
662
ite (by simpa using hp.comp Primrec.id hf) (option_some_iff.2 hf) (const none)
631
663
@@ -634,7 +666,7 @@ theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Op
634
666
635
667
protected theorem decode₂ : Primrec (decode₂ α) :=
636
668
option_bind .decode <|
637
- option_guard (Primrec.beq .comp₂ (by exact encode_iff.mpr snd) (by exact fst.comp fst)) snd
669
+ option_guard (Primrec.eq .comp₂ (by exact encode_iff.mpr snd) (by exact fst.comp fst)) snd
638
670
639
671
theorem list_findIdx₁ {p : α → β → Bool} (hp : Primrec₂ p) :
640
672
∀ l : List β, Primrec fun a => l.findIdx (p a)
@@ -659,7 +691,7 @@ theorem dom_fintype [Finite α] (f : α → σ) : Primrec f :=
659
691
def PrimrecBounded (f : α → β) : Prop :=
660
692
∃ g : α → ℕ, Primrec g ∧ ∀ x, encode (f x) ≤ g x
661
693
662
- theorem nat_findGreatest {f : α → ℕ} {p : α → ℕ → Prop } [∀ x n, Decidable (p x n) ]
694
+ theorem nat_findGreatest {f : α → ℕ} {p : α → ℕ → Prop } [DecidableRel p ]
663
695
(hf : Primrec f) (hp : PrimrecRel p) : Primrec fun x => (f x).findGreatest (p x) :=
664
696
(nat_rec' (h := fun x nih => if p x (nih.1 + 1 ) then nih.1 + 1 else nih.2 )
665
697
hf (const 0 ) (ite (hp.comp fst (snd |> fst.comp |> succ.comp))
@@ -1091,19 +1123,21 @@ namespace PrimrecPred
1091
1123
1092
1124
open List Primrec
1093
1125
1094
- variable {α β : Type *} {p : α → Prop } [DecidablePred p] {L : List α} {b : β}
1126
+ variable {α β : Type *} {p : α → Prop } {L : List α} {b : β}
1095
1127
1096
1128
variable [Primcodable α] [Primcodable β]
1097
1129
1098
1130
/-- Checking if any element of a list satisfies a decidable predicate is primitive recursive. -/
1099
- theorem exists_mem_list (hf : PrimrecPred p) : PrimrecPred fun L : List α ↦ ∃ a ∈ L, p a :=
1100
- .of_eq (.not <| PrimrecRel.comp .eq (list_length.comp <| listFilter hf) (const 0 )) <| by simp
1131
+ theorem exists_mem_list : (hf : PrimrecPred p) → PrimrecPred fun L : List α ↦ ∃ a ∈ L, p a
1132
+ | ⟨_, hf⟩ => .of_eq
1133
+ (.not <| Primrec.eq.comp (list_length.comp <| listFilter hf.primrecPred) (const 0 )) <| by simp
1101
1134
1102
1135
/-- Checking if every element of a list satisfies a decidable predicate is primitive recursive. -/
1103
- theorem forall_mem_list (hf : PrimrecPred p) : PrimrecPred fun L : List α ↦ ∀ a ∈ L, p a :=
1104
- .of_eq (PrimrecRel.comp .eq (list_length.comp <| listFilter hf) (list_length)) <| by simp
1136
+ theorem forall_mem_list : (hf : PrimrecPred p) → PrimrecPred fun L : List α ↦ ∀ a ∈ L, p a
1137
+ | ⟨_, hf⟩ => .of_eq
1138
+ (Primrec.eq.comp (list_length.comp <| listFilter hf.primrecPred) (list_length)) <| by simp
1105
1139
1106
- variable {p : ℕ → Prop } [DecidablePred p]
1140
+ variable {p : ℕ → Prop }
1107
1141
1108
1142
/-- Bounded existential quantifiers are primitive recursive. -/
1109
1143
theorem exists_lt (hf : PrimrecPred p) : PrimrecPred fun n ↦ ∃ x < n, p x :=
@@ -1118,45 +1152,47 @@ theorem listFilter_listRange {R : ℕ → ℕ → Prop} (s : ℕ) [DecidableRel
1118
1152
Primrec fun n ↦ (range s).filter (fun y ↦ R y n) := by
1119
1153
simp only [← filterMap_eq_filter]
1120
1154
refine listFilterMap (.const (range s)) ?_
1121
- refine ite (PrimrecRel.comp .eq ?_ (const true )) (option_some_iff.mpr snd) (.const Option.none)
1122
- exact hf.comp snd fst
1155
+ refine ite (Primrec.eq.comp ?_ (const true )) (option_some_iff.mpr snd) (.const Option.none)
1156
+ exact hf.decide. comp snd fst
1123
1157
1124
1158
end PrimrecPred
1125
1159
1126
1160
namespace PrimrecRel
1127
1161
1128
1162
open Primrec List PrimrecPred
1129
1163
1130
- variable {α β : Type *} {R : α → β → Prop } [DecidableRel R] {L : List α} {b : β}
1164
+ variable {α β : Type *} {R : α → β → Prop } {L : List α} {b : β}
1131
1165
1132
1166
variable [Primcodable α] [Primcodable β]
1133
1167
1134
1168
protected theorem not (hf : PrimrecRel R) : PrimrecRel fun a b ↦ ¬ R a b := PrimrecPred.not hf
1135
1169
1136
1170
/-- If `R a b` is decidable, then given `L : List α` and `b : β`, it is primitive recurisve
1137
1171
to filter `L` for elements `a` with `R a b` -/
1138
- theorem listFilter (hf : PrimrecRel R) :
1172
+ theorem listFilter (hf : PrimrecRel R) [DecidableRel R] :
1139
1173
Primrec₂ fun (L : List α) b ↦ L.filter (fun a ↦ R a b) := by
1140
1174
simp only [← List.filterMap_eq_filter]
1141
1175
refine listFilterMap fst (Primrec.ite ?_ ?_ (Primrec.const Option.none))
1142
- · exact PrimrecRel. comp .eq (hf.comp snd (snd.comp fst)) (.const true )
1176
+ · exact Primrec.eq. comp (hf.decide .comp snd (snd.comp fst)) (.const true )
1143
1177
· exact (option_some).comp snd
1144
1178
1145
1179
/-- If `R a b` is decidable, then given `L : List α` and `b : β`, `g L b ↔ ∃ a L, R a b`
1146
1180
is a primitive recursive relation. -/
1147
1181
theorem exists_mem_list (hf : PrimrecRel R) : PrimrecRel fun (L : List α) b ↦ ∃ a ∈ L, R a b := by
1182
+ classical
1148
1183
have h (L) (b) : (List.filter (R · b) L).length ≠ 0 ↔ ∃ a ∈ L, R a b := by simp
1149
1184
refine .of_eq (.not ?_) h
1150
- exact .comp .eq (list_length.comp hf.listFilter) (const 0 )
1185
+ exact Primrec.eq.comp (list_length.comp hf.listFilter) (const 0 )
1151
1186
1152
1187
/-- If `R a b` is decidable, then given `L : List α` and `b : β`, `g L b ↔ ∀ a L, R a b`
1153
1188
is a primitive recursive relation. -/
1154
1189
theorem forall_mem_list (hf : PrimrecRel R) : PrimrecRel fun (L : List α) b ↦ ∀ a ∈ L, R a b := by
1190
+ classical
1155
1191
have h (L) (b) : (List.filter (R · b) L).length = L.length ↔ ∀ a ∈ L, R a b := by simp
1156
1192
apply PrimrecRel.of_eq ?_ h
1157
- exact (.comp .eq (list_length.comp <| PrimrecRel.listFilter hf) (.comp list_length fst))
1193
+ exact (Primrec.eq.comp (list_length.comp <| PrimrecRel.listFilter hf) (.comp list_length fst))
1158
1194
1159
- variable {R : ℕ → ℕ → Prop } [DecidableRel R]
1195
+ variable {R : ℕ → ℕ → Prop }
1160
1196
1161
1197
/-- If `R a b` is decidable, then for any fixed `n` and `y`, `g n y ↔ ∃ x < n, R x y` is a
1162
1198
primitive recursive relation. -/
@@ -1179,7 +1215,7 @@ open Primrec
1179
1215
/-- A subtype of a primitive recursive predicate is `Primcodable`. -/
1180
1216
def subtype {p : α → Prop } [DecidablePred p] (hp : PrimrecPred p) : Primcodable (Subtype p) :=
1181
1217
⟨have : Primrec fun n => (@decode α _ n).bind fun a => Option.guard p a :=
1182
- option_bind .decode (option_guard (hp.comp snd).to₂ snd)
1218
+ option_bind .decode (option_guard (hp.comp snd).primrecRel snd)
1183
1219
nat_iff.1 <| (encode_iff.2 this).of_eq fun n =>
1184
1220
show _ = encode ((@decode α _ n).bind fun _ => _) by
1185
1221
rcases @decode α _ n with - | a; · rfl
@@ -1190,7 +1226,7 @@ instance fin {n} : Primcodable (Fin n) :=
1190
1226
@ofEquiv _ _ (subtype <| nat_lt.comp .id (const n)) Fin.equivSubtype
1191
1227
1192
1228
instance vector {n} : Primcodable (List.Vector α n) :=
1193
- subtype ((@Primrec.eq ℕ _ _ ).comp list_length (const _))
1229
+ subtype ((@Primrec.eq ℕ _).comp list_length (const _))
1194
1230
1195
1231
instance finArrow {n} : Primcodable (Fin n → α) :=
1196
1232
ofEquiv _ (Equiv.vectorEquivFin _ _).symm
0 commit comments