-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDecidability.lean
126 lines (106 loc) · 3.81 KB
/
Decidability.lean
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
-- A complete translation to Lean from Agda of
-- https://github.com/conal/paper-2021-language-derivatives/blob/main/Decidability.lagda
-- except for the explicit TODOs found in this file.
import Sadol.Function
namespace Decidability
-- Agda:
-- data Dec (A: Set l):Set l where
-- yes: A → Dec A
-- no :¬A → Dec A
-- Lean Prop:
-- class inductive Decidable (p : Prop) where
-- | isFalse (h : Not p) : Decidable p
-- | isTrue (h : p) : Decidable p
class inductive Dec (P: Type u): Type u where
| yes: P -> Dec P
| no: (P -> PEmpty.{u + 1}) -> Dec P
-- Agda:
-- Decidable : (X → Set ℓ) → Set ℓ
-- Decidable P = ∀ x → Dec (P x)
-- Lean Prop:
-- abbrev DecidablePred {α : Sort u} (r : α → Prop) :=
-- (a : α) → Decidable (r a)
abbrev DecPred {α : Type u} (P : α → Type u) :=
(a : α) → Dec (P a)
-- Agda
-- Decidable₂ : (A → B → Set ℓ) → Set ℓ
-- Decidable₂ _∼_ = ∀ a b → Dec (a ∼ b)
-- Lean Prop:
-- abbrev DecidableRel {α : Sort u} (r : α → α → Prop) :=
-- (a b : α) → Decidable (r a b)
abbrev DecRel {α : Type u} (r : α → α → Type u) :=
(a b : α) → Dec (r a b)
-- ¬⇃_ : Set ℓ → Set ℓ
-- ¬⇃ X = X → ⊥
def not (α: Type u): Type u :=
α -> PEmpty.{u + 1}
abbrev DecEq (α : Type u) :=
(a b : α) → Dec (a ≡ b)
-- module Symbolic {ℓ} {A : Set ℓ} (_≟_ : Decidable₂ {A = A} _≡_) where
def decEq {α : Type u} [inst : DecEq α] (a b : α) : Dec (a ≡ b) :=
inst a b
-- ⊥? : Dec ⊥
-- ⊥? = no(𝜆())
def empty : Dec PEmpty :=
Dec.no (by intro; contradiction)
-- ⊤‽ : Dec ⊤
-- ⊤‽ = yes tt
def unit : Dec PUnit :=
Dec.yes PUnit.unit
-- _⊎‽_ : Dec A → Dec B → Dec (A ⊎ B)
-- no ¬a ⊎‽ no ¬b = no [ ¬a , ¬b ]
-- yes a ⊎‽ no ¬b = yes (inj₁ a)
-- _ ⊎‽ yes b = yes (inj₂ b)
def sum {α β: Type u} (a: Dec α) (b: Dec β): Dec (α ⊕ β) :=
match (a, b) with
| (Dec.no a, Dec.no b) =>
Dec.no (fun ab =>
match ab with
| Sum.inl sa => a sa
| Sum.inr sb => b sb
)
| (Dec.yes a, Dec.no _) =>
Dec.yes (Sum.inl a)
| (_, Dec.yes b) =>
Dec.yes (Sum.inr b)
-- _×‽_ : Dec A → Dec B → Dec (A × B)
-- yes a ×‽ yes b = yes (a , b)
-- no ¬a ×‽ yes b = no (¬a ∘ proj₁)
-- _ ×‽ no ¬b = no (¬b ∘ proj₂)
def prod {α β: Type u} (a: Dec α) (b: Dec β): Dec (α × β) :=
match (a, b) with
| (Dec.yes a, Dec.yes b) => Dec.yes (Prod.mk a b)
| (Dec.no a, Dec.yes _) => Dec.no (fun ⟨a', _⟩ => a a')
| (_, Dec.no b) => Dec.no (fun ⟨_, b'⟩ => b b')
-- _✶‽ : Dec A → Dec (A ✶)
-- _ ✶‽ = yes []
def list {α: Type u}: Dec α -> Dec (List α) :=
fun _ => Dec.yes []
-- map′ : (A → B) → (B → A) → Dec A → Dec B
-- map′ A→B B→A (yes a) = yes (A→B a)
-- map′ A→B B→A (no ¬a) = no (¬a ∘ B→A)
def map' {α β: Type u} (ab: α -> β) (ba: β -> α) (deca: Dec α): Dec β :=
match deca with
| Dec.yes a =>
Dec.yes (ab a)
| Dec.no nota =>
Dec.no (nota ∘ ba)
-- map‽⇔ : A ⇔ B → Dec A → Dec B
-- map‽⇔ A⇔B = map′ (to ⟨$⟩_) (from ⟨$⟩_) where open Equivalence A⇔B
def map {α β: Type u} (ab: α <=> β) (deca: Dec α): Dec β :=
map' ab.toFun ab.invFun deca
-- _▹_ : A ↔ B → Dec A → Dec B
-- f ▹ a? = map‽⇔ (↔→⇔ f) a?
def apply {α β: Type u} (f: α <=> β) (deca: Dec α): Dec β :=
map f deca
-- TODO: rewrite Agda into Lean
-- _▸_ : (P ⟷ Q) → Decidable P → Decidable Q
-- (f ▸ p?) w = f ▹ p? w
-- _◃_ : B ↔ A → Dec A → Dec B
-- g ◃ a? = ↔Eq.sym g ▹ a?
def apply' {α β: Type u} (f: β <=> α) (deca: Dec α): Dec β :=
map f.sym deca
-- TODO: rewrite Agda into Lean
-- _◂_ : Q ⟷ P → Decidable P → Decidable Q
-- (g ◂ p?) w = g ◃ p? w
end Decidability