22-- Phronesis Formalization in Agda
33-- Intrinsically typed representation with dependent types
44
5+ {-# OPTIONS --safe --without-K #-}
6+
57module Phronesis where
68
79open import Data.Nat using (ℕ; zero; suc; _+_; _≤_)
@@ -35,20 +37,115 @@ data PhrType : Set where
3537-- 2. Type Equality Decidability
3638-- ═══════════════════════════════════════════════════════════════════════════
3739
38- -- Decidable equality for types (needed for type checking)
39- _≟ᵗ_ : (τ₁ τ₂ : PhrType) → Dec (τ₁ ≡ τ₂)
40- TInt ≟ᵗ TInt = yes refl
41- TBool ≟ᵗ TBool = yes refl
42- TString ≟ᵗ TString = yes refl
43- TNull ≟ᵗ TNull = yes refl
44- TFloat ≟ᵗ TFloat = yes refl
45- TIP ≟ᵗ TIP = yes refl
46- TDateTime ≟ᵗ TDateTime = yes refl
47- TList τ₁ ≟ᵗ TList τ₂ with τ₁ ≟ᵗ τ₂
48- ... | yes refl = yes refl
49- ... | no ¬p = no (λ { refl → ¬p refl })
50- -- ... other cases omitted for brevity
51- _ ≟ᵗ _ = no (λ ())
40+ -- Decidable equality for types (needed for type checking).
41+ --
42+ -- TRecord nests through List (String × PhrType), so the field list is decided
43+ -- mutually (_≟ᶠ_). EVERY same-head case — including TRecord — is handled
44+ -- explicitly *above* the final catch-all, so the catch-all covers only
45+ -- distinct-head pairs and `no (λ ())` is sound. (The previous version omitted
46+ -- the TRecord case, which made the catch-all unsound: `TRecord fs ≡ TRecord gs`
47+ -- is inhabited by `refl`, so `λ ()` did not typecheck under --safe.)
48+ mutual
49+ _≟ᵗ_ : (τ₁ τ₂ : PhrType) → Dec (τ₁ ≡ τ₂)
50+ TInt ≟ᵗ TInt = yes refl
51+ TBool ≟ᵗ TBool = yes refl
52+ TString ≟ᵗ TString = yes refl
53+ TNull ≟ᵗ TNull = yes refl
54+ TFloat ≟ᵗ TFloat = yes refl
55+ TIP ≟ᵗ TIP = yes refl
56+ TDateTime ≟ᵗ TDateTime = yes refl
57+ TList τ₁ ≟ᵗ TList τ₂ with τ₁ ≟ᵗ τ₂
58+ ... | yes refl = yes refl
59+ ... | no ¬p = no (λ { refl → ¬p refl })
60+ TRecord fs ≟ᵗ TRecord gs with fs ≟ᶠ gs
61+ ... | yes refl = yes refl
62+ ... | no ¬p = no (λ { refl → ¬p refl })
63+ -- distinct-head pairs (all absurd; enumerated because Agda will not refine a
64+ -- single `_ ≟ᵗ _` catch-all to the distinct-head cases under --safe):
65+ TInt ≟ᵗ TFloat = no (λ ())
66+ TInt ≟ᵗ TString = no (λ ())
67+ TInt ≟ᵗ TBool = no (λ ())
68+ TInt ≟ᵗ TIP = no (λ ())
69+ TInt ≟ᵗ TDateTime = no (λ ())
70+ TInt ≟ᵗ TList _ = no (λ ())
71+ TInt ≟ᵗ TRecord _ = no (λ ())
72+ TInt ≟ᵗ TNull = no (λ ())
73+ TFloat ≟ᵗ TInt = no (λ ())
74+ TFloat ≟ᵗ TString = no (λ ())
75+ TFloat ≟ᵗ TBool = no (λ ())
76+ TFloat ≟ᵗ TIP = no (λ ())
77+ TFloat ≟ᵗ TDateTime = no (λ ())
78+ TFloat ≟ᵗ TList _ = no (λ ())
79+ TFloat ≟ᵗ TRecord _ = no (λ ())
80+ TFloat ≟ᵗ TNull = no (λ ())
81+ TString ≟ᵗ TInt = no (λ ())
82+ TString ≟ᵗ TFloat = no (λ ())
83+ TString ≟ᵗ TBool = no (λ ())
84+ TString ≟ᵗ TIP = no (λ ())
85+ TString ≟ᵗ TDateTime = no (λ ())
86+ TString ≟ᵗ TList _ = no (λ ())
87+ TString ≟ᵗ TRecord _ = no (λ ())
88+ TString ≟ᵗ TNull = no (λ ())
89+ TBool ≟ᵗ TInt = no (λ ())
90+ TBool ≟ᵗ TFloat = no (λ ())
91+ TBool ≟ᵗ TString = no (λ ())
92+ TBool ≟ᵗ TIP = no (λ ())
93+ TBool ≟ᵗ TDateTime = no (λ ())
94+ TBool ≟ᵗ TList _ = no (λ ())
95+ TBool ≟ᵗ TRecord _ = no (λ ())
96+ TBool ≟ᵗ TNull = no (λ ())
97+ TIP ≟ᵗ TInt = no (λ ())
98+ TIP ≟ᵗ TFloat = no (λ ())
99+ TIP ≟ᵗ TString = no (λ ())
100+ TIP ≟ᵗ TBool = no (λ ())
101+ TIP ≟ᵗ TDateTime = no (λ ())
102+ TIP ≟ᵗ TList _ = no (λ ())
103+ TIP ≟ᵗ TRecord _ = no (λ ())
104+ TIP ≟ᵗ TNull = no (λ ())
105+ TDateTime ≟ᵗ TInt = no (λ ())
106+ TDateTime ≟ᵗ TFloat = no (λ ())
107+ TDateTime ≟ᵗ TString = no (λ ())
108+ TDateTime ≟ᵗ TBool = no (λ ())
109+ TDateTime ≟ᵗ TIP = no (λ ())
110+ TDateTime ≟ᵗ TList _ = no (λ ())
111+ TDateTime ≟ᵗ TRecord _ = no (λ ())
112+ TDateTime ≟ᵗ TNull = no (λ ())
113+ TList _ ≟ᵗ TInt = no (λ ())
114+ TList _ ≟ᵗ TFloat = no (λ ())
115+ TList _ ≟ᵗ TString = no (λ ())
116+ TList _ ≟ᵗ TBool = no (λ ())
117+ TList _ ≟ᵗ TIP = no (λ ())
118+ TList _ ≟ᵗ TDateTime = no (λ ())
119+ TList _ ≟ᵗ TRecord _ = no (λ ())
120+ TList _ ≟ᵗ TNull = no (λ ())
121+ TRecord _ ≟ᵗ TInt = no (λ ())
122+ TRecord _ ≟ᵗ TFloat = no (λ ())
123+ TRecord _ ≟ᵗ TString = no (λ ())
124+ TRecord _ ≟ᵗ TBool = no (λ ())
125+ TRecord _ ≟ᵗ TIP = no (λ ())
126+ TRecord _ ≟ᵗ TDateTime = no (λ ())
127+ TRecord _ ≟ᵗ TList _ = no (λ ())
128+ TRecord _ ≟ᵗ TNull = no (λ ())
129+ TNull ≟ᵗ TInt = no (λ ())
130+ TNull ≟ᵗ TFloat = no (λ ())
131+ TNull ≟ᵗ TString = no (λ ())
132+ TNull ≟ᵗ TBool = no (λ ())
133+ TNull ≟ᵗ TIP = no (λ ())
134+ TNull ≟ᵗ TDateTime = no (λ ())
135+ TNull ≟ᵗ TList _ = no (λ ())
136+ TNull ≟ᵗ TRecord _ = no (λ ())
137+
138+ -- Decidable equality for record field lists.
139+ _≟ᶠ_ : (fs gs : List (String × PhrType)) → Dec (fs ≡ gs)
140+ [] ≟ᶠ [] = yes refl
141+ [] ≟ᶠ (_ ∷ _) = no (λ ())
142+ (_ ∷ _) ≟ᶠ [] = no (λ ())
143+ ((s₁ , τ₁) ∷ fs) ≟ᶠ ((s₂ , τ₂) ∷ gs)
144+ with Data.String._≟_ s₁ s₂ | τ₁ ≟ᵗ τ₂ | fs ≟ᶠ gs
145+ ... | yes refl | yes refl | yes refl = yes refl
146+ ... | no ¬p | _ | _ = no (λ { refl → ¬p refl })
147+ ... | _ | no ¬p | _ = no (λ { refl → ¬p refl })
148+ ... | _ | _ | no ¬p = no (λ { refl → ¬p refl })
52149
53150-- ═══════════════════════════════════════════════════════════════════════════
54151-- 3. Semantic Domain (Values indexed by Type)
@@ -72,15 +169,15 @@ _ ≟ᵗ _ = no (λ ())
72169-- ═══════════════════════════════════════════════════════════════════════════
73170
74171data Ctx : Set where
75- ∅ : Ctx
76- _,_ : Ctx → String × PhrType → Ctx
172+ ∅ : Ctx
173+ _,, _ : Ctx → String × PhrType → Ctx
77174
78- infixl 5 _,_
175+ infixl 5 _,, _
79176
80177-- Variable lookup (de Bruijn style would be cleaner, but using names for clarity)
81178data _∋_∶_ : Ctx → String → PhrType → Set where
82- here : ∀ {Γ x τ} → (Γ , (x , τ)) ∋ x ∶ τ
83- there : ∀ {Γ x y τ τ'} → Γ ∋ x ∶ τ → (Γ , (y , τ')) ∋ x ∶ τ
179+ here : ∀ {Γ x τ} → (Γ ,, (x , τ)) ∋ x ∶ τ
180+ there : ∀ {Γ x y τ τ'} → Γ ∋ x ∶ τ → (Γ ,, (y , τ')) ∋ x ∶ τ
84181
85182-- ═══════════════════════════════════════════════════════════════════════════
86183-- 5. Intrinsically Typed Expressions
@@ -130,7 +227,7 @@ infix 5 _==ᵉ_ _<ᵉ_
130227
131228data Env : Ctx → Set where
132229 ε : Env ∅
133- _▷_ : ∀ {Γ x τ} → Env Γ → ⟦ τ ⟧ → Env (Γ , (x , τ))
230+ _▷_ : ∀ {Γ x τ} → Env Γ → ⟦ τ ⟧ → Env (Γ ,, (x , τ))
134231
135232infixl 5 _▷_
136233
@@ -143,12 +240,12 @@ lookupEnv (there x) (ρ ▷ _) = lookupEnv x ρ
143240-- 7. Denotational Semantics (Evaluation)
144241-- ═══════════════════════════════════════════════════════════════════════════
145242
146- open import Data.Integer using (_+_; _-_; _*_; _ ≤ᵇ_) renaming (_+_ to _+ℤ_; _-_ to _-ℤ_; _*_ to _*ℤ_)
243+ open import Data.Integer using (_≤ᵇ_) renaming (_+_ to _+ℤ_; _-_ to _-ℤ_; _*_ to _*ℤ_)
147244
148245-- Value equality (for comparison operators)
149246-- Implemented via decidable equality per type, not postulated.
150247
151- open import Data.Integer using (_≟_ ) renaming (_≟_ to _≟ℤ_)
248+ open import Data.Integer using () renaming (_≟_ to _≟ℤ_)
152249open import Data.String using () renaming (_≟_ to _≟ˢ_)
153250open import Data.Nat using () renaming (_≟_ to _≟ⁿ_)
154251open import Data.Bool using () renaming (_≟_ to _≟ᵇ_)
@@ -196,10 +293,10 @@ mutual
196293 eqRecord {[]} tt tt = true
197294 eqRecord {(_ , τ) ∷ fs} (v , vs) (w , ws) = _≡ᵛ_ v w ∧ eqRecord {fs} vs ws
198295
199- -- Integer less-than via the standard library ordering.
296+ -- Integer less-than via the standard library ordering. The parentheses are
297+ -- load-bearing (`_∧_` binds tighter than `_≤ᵇ_`); `_≡ᵛ_` is indexed at TInt.
200298_<ᵛ_ : ℤ → ℤ → Bool
201- a <ᵛ b = a ≤ᵇ b ∧ not (a ≡ᵛ b)
202- where open import Data.Integer using (_≤ᵇ_)
299+ a <ᵛ b = (a ≤ᵇ b) ∧ not (_≡ᵛ_ {TInt} a b)
203300
204301-- List membership via value equality.
205302_∈ᵛ_ : ∀ {τ} → ⟦ τ ⟧ → List ⟦ τ ⟧ → Bool
0 commit comments