open import Atom
module Not-the-code-of (atoms : χ-atoms) where
open import Equality.Propositional
open import Prelude hiding (const)
open import Tactic.By.Propositional
open import Injection equality-with-J using (Injective)
open import Maybe equality-with-J
open import Monad equality-with-J
open import Chi atoms
open import Coding atoms
import Coding.Instances atoms as I
open import Constants atoms
open χ-atoms atoms
mutual
data Expᴱ : Type where
apply : Expᴱ → Expᴱ → Expᴱ
lambda : Var → Expᴱ → Expᴱ
case : Expᴱ → List Brᴱ → Expᴱ
rec : Var → Expᴱ → Expᴱ
var : Var → Expᴱ
const : Const → List Expᴱ → Expᴱ
⌞_⌟ : Exp → Expᴱ
data Brᴱ : Type where
branch : Const → List Var → Expᴱ → Brᴱ
mutual
⌜_⌝E : Expᴱ → Exp
⌜ apply e₁ e₂ ⌝E = const c-apply (⌜ e₁ ⌝E ∷ ⌜ e₂ ⌝E ∷ [])
⌜ lambda x e ⌝E = const c-lambda (⌜ x ⌝ ∷ ⌜ e ⌝E ∷ [])
⌜ case e bs ⌝E = const c-case (⌜ e ⌝E ∷ ⌜ bs ⌝B⋆ ∷ [])
⌜ rec x e ⌝E = const c-rec (⌜ x ⌝ ∷ ⌜ e ⌝E ∷ [])
⌜ var x ⌝E = const c-var (⌜ x ⌝ ∷ [])
⌜ const c es ⌝E = const c-const (⌜ c ⌝ ∷ ⌜ es ⌝E⋆ ∷ [])
⌜ ⌞ e ⌟ ⌝E = e
⌜_⌝B : Brᴱ → Exp
⌜ branch c xs e ⌝B = const c-branch (⌜ c ⌝ ∷ ⌜ xs ⌝ ∷ ⌜ e ⌝E ∷ [])
⌜_⌝E⋆ : List Expᴱ → Exp
⌜ [] ⌝E⋆ = const c-nil []
⌜ e ∷ es ⌝E⋆ = const c-cons (⌜ e ⌝E ∷ ⌜ es ⌝E⋆ ∷ [])
⌜_⌝B⋆ : List Brᴱ → Exp
⌜ [] ⌝B⋆ = const c-nil []
⌜ b ∷ bs ⌝B⋆ = const c-cons (⌜ b ⌝B ∷ ⌜ bs ⌝B⋆ ∷ [])
not-injective : ¬ Injective ⌜_⌝E
not-injective =
Injective ⌜_⌝E →⟨ (λ hyp → hyp) ⟩
(⌜ var v-x ⌝E ≡ ⌜ ⌞ ⌜ var v-x ⌝ ⌟ ⌝E → var v-x ≡ ⌞ ⌜ var v-x ⌝ ⌟) →⟨ _$ refl ⟩
var v-x ≡ ⌞ ⌜ var v-x ⌝ ⌟ →⟨ (λ ()) ⟩□
⊥ □
private
mutual
cod : Exp → Expᴱ
cod (apply e₁ e₂) = apply (cod e₁) (cod e₂)
cod (lambda x e) = lambda x (cod e)
cod (case e bs) = case (cod e) (codB⋆ bs)
cod (rec x e) = rec x (cod e)
cod (var x) = var x
cod (const c es) = const c (cod⋆ es)
codB : Br → Brᴱ
codB (branch c xs e) = branch c xs (cod e)
cod⋆ : List Exp → List Expᴱ
cod⋆ [] = []
cod⋆ (e ∷ es) = cod e ∷ cod⋆ es
codB⋆ : List Br → List Brᴱ
codB⋆ [] = []
codB⋆ (e ∷ es) = codB e ∷ codB⋆ es
mutual
dec : Expᴱ → Maybe Exp
dec (apply e₁ e₂) = apply ⟨$⟩ dec e₁ ⊛ dec e₂
dec (lambda x e) = lambda x ⟨$⟩ dec e
dec (case e bs) = case ⟨$⟩ dec e ⊛ decB⋆ bs
dec (rec x e) = rec x ⟨$⟩ dec e
dec (var x) = return (var x)
dec (const c es) = const c ⟨$⟩ dec⋆ es
dec ⌞ _ ⌟ = nothing
decB : Brᴱ → Maybe Br
decB (branch c xs e) = branch c xs ⟨$⟩ dec e
dec⋆ : List Expᴱ → Maybe (List Exp)
dec⋆ [] = return []
dec⋆ (e ∷ es) = _∷_ ⟨$⟩ dec e ⊛ dec⋆ es
decB⋆ : List Brᴱ → Maybe (List Br)
decB⋆ [] = return []
decB⋆ (e ∷ es) = _∷_ ⟨$⟩ decB e ⊛ decB⋆ es
mutual
dec-cod : ∀ e → dec (cod e) ≡ just e
dec-cod (apply e₁ e₂) =
apply ⟨$⟩ ⟨ dec (cod e₁) ⟩ ⊛ dec (cod e₂) ≡⟨ ⟨by⟩ (dec-cod e₁) ⟩
apply ⟨$⟩ return e₁ ⊛ ⟨ dec (cod e₂) ⟩ ≡⟨ ⟨by⟩ (dec-cod e₂) ⟩
apply ⟨$⟩ return e₁ ⊛ return e₂ ≡⟨⟩
return (apply e₁ e₂) ∎
dec-cod (lambda x e) =
lambda x ⟨$⟩ ⟨ dec (cod e) ⟩ ≡⟨ ⟨by⟩ (dec-cod e) ⟩
lambda x ⟨$⟩ return e ≡⟨⟩
return (lambda x e) ∎
dec-cod (case e bs) =
case ⟨$⟩ ⟨ dec (cod e) ⟩ ⊛ decB⋆ (codB⋆ bs) ≡⟨ ⟨by⟩ (dec-cod e) ⟩
case ⟨$⟩ return e ⊛ ⟨ decB⋆ (codB⋆ bs) ⟩ ≡⟨ ⟨by⟩ (dec-codB⋆ bs) ⟩
case ⟨$⟩ return e ⊛ return bs ≡⟨⟩
return (case e bs) ∎
dec-cod (rec x e) =
rec x ⟨$⟩ ⟨ dec (cod e) ⟩ ≡⟨ ⟨by⟩ (dec-cod e) ⟩
rec x ⟨$⟩ return e ≡⟨⟩
return (rec x e) ∎
dec-cod (var x) =
return (var x) ∎
dec-cod (const c es) =
const c ⟨$⟩ ⟨ dec⋆ (cod⋆ es) ⟩ ≡⟨ ⟨by⟩ (dec-cod⋆ es) ⟩
const c ⟨$⟩ return es ≡⟨⟩
return (const c es) ∎
dec-codB : ∀ b → decB (codB b) ≡ just b
dec-codB (branch c xs e) =
branch c xs ⟨$⟩ ⟨ dec (cod e) ⟩ ≡⟨ ⟨by⟩ (dec-cod e) ⟩
branch c xs ⟨$⟩ return e ≡⟨⟩
return (branch c xs e) ∎
dec-cod⋆ : ∀ es → dec⋆ (cod⋆ es) ≡ just es
dec-cod⋆ [] =
return [] ∎
dec-cod⋆ (e ∷ es) =
_∷_ ⟨$⟩ ⟨ dec (cod e) ⟩ ⊛ dec⋆ (cod⋆ es) ≡⟨ ⟨by⟩ (dec-cod e) ⟩
_∷_ ⟨$⟩ return e ⊛ ⟨ dec⋆ (cod⋆ es) ⟩ ≡⟨ ⟨by⟩ (dec-cod⋆ es) ⟩
_∷_ ⟨$⟩ return e ⊛ return es ≡⟨⟩
return (e ∷ es) ∎
dec-codB⋆ : ∀ bs → decB⋆ (codB⋆ bs) ≡ just bs
dec-codB⋆ [] =
return [] ∎
dec-codB⋆ (b ∷ bs) =
_∷_ ⟨$⟩ ⟨ decB (codB b) ⟩ ⊛ decB⋆ (codB⋆ bs) ≡⟨ ⟨by⟩ (dec-codB b) ⟩
_∷_ ⟨$⟩ return b ⊛ ⟨ decB⋆ (codB⋆ bs) ⟩ ≡⟨ ⟨by⟩ (dec-codB⋆ bs) ⟩
_∷_ ⟨$⟩ return b ⊛ return bs ≡⟨⟩
return (b ∷ bs) ∎
code-Exp-Expᴱ : Code Exp Expᴱ
code-Exp-Expᴱ .code = cod
code-Exp-Expᴱ .decode = dec
code-Exp-Expᴱ .decode∘code = dec-cod
code-Br-Brᴱ : Code Br Brᴱ
code-Br-Brᴱ .code = codB
code-Br-Brᴱ .decode = decB
code-Br-Brᴱ .decode∘code = dec-codB
code-List-Exp-List-Expᴱ : Code (List Exp) (List Expᴱ)
code-List-Exp-List-Expᴱ .code = cod⋆
code-List-Exp-List-Expᴱ .decode = dec⋆
code-List-Exp-List-Expᴱ .decode∘code = dec-cod⋆
code-List-Br-List-Brᴱ : Code (List Br) (List Brᴱ)
code-List-Br-List-Brᴱ .code = codB⋆
code-List-Br-List-Brᴱ .decode = decB⋆
code-List-Br-List-Brᴱ .decode∘code = dec-codB⋆
instance
rep-Exp-Expᴱ : Rep Exp Expᴱ
rep-Exp-Expᴱ = rep ⦃ code-Exp-Expᴱ ⦄
rep-Br-Brᴱ : Rep Br Brᴱ
rep-Br-Brᴱ = rep ⦃ code-Br-Brᴱ ⦄
rep-List-Exp-List-Expᴱ : Rep (List Exp) (List Expᴱ)
rep-List-Exp-List-Expᴱ = rep ⦃ code-List-Exp-List-Expᴱ ⦄
rep-List-Br-List-Brᴱ : Rep (List Br) (List Brᴱ)
rep-List-Br-List-Brᴱ = rep ⦃ code-List-Br-List-Brᴱ ⦄
mutual
⌜⌜⌝⌝E≡⌜⌝ : (e : Exp) → ⌜ ⌜ e ⌝ ⌝E ≡ ⌜ e ⌝
⌜⌜⌝⌝E≡⌜⌝ e = ⌜⌜⌝⌝E≡⌜⌝′ e
where
⌜⌜⌝⌝E≡⌜⌝′ : (e : Exp) → ⌜ ⌜ e ⌝ ⌝E ≡ ⌜ e ⌝
⌜⌜⌝⌝E≡⌜⌝′ (apply e₁ e₂) =
Exp.const c-apply (⟨ ⌜ ⌜ e₁ ⌝ ⌝E ⟩ ∷ ⌜ ⌜ e₂ ⌝ ⌝E ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e₁) ⟩
const c-apply (⌜ e₁ ⌝ ∷ ⟨ ⌜ ⌜ e₂ ⌝ ⌝E ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e₂) ⟩∎
const c-apply (⌜ e₁ ⌝ ∷ ⌜ e₂ ⌝ ∷ []) ∎
⌜⌜⌝⌝E≡⌜⌝′ (lambda x e) =
Exp.const c-lambda (⌜ x ⌝ ∷ ⟨ ⌜ ⌜ e ⌝ ⌝E ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e) ⟩∎
const c-lambda (⌜ x ⌝ ∷ ⌜ e ⌝ ∷ []) ∎
⌜⌜⌝⌝E≡⌜⌝′ (case e bs) =
Exp.const c-case (⟨ ⌜ ⌜ e ⌝ ⌝E ⟩ ∷ ⌜ ⌜ bs ⌝ ⌝B⋆ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e) ⟩
const c-case (⌜ e ⌝ ∷ ⟨ ⌜ ⌜ bs ⌝ ⌝B⋆ ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝B⋆≡⌜⌝ bs) ⟩∎
const c-case (⌜ e ⌝ ∷ ⌜ bs ⌝ ∷ []) ∎
⌜⌜⌝⌝E≡⌜⌝′ (rec x e) =
Exp.const c-rec (⌜ x ⌝ ∷ ⟨ ⌜ ⌜ e ⌝ ⌝E ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e) ⟩∎
const c-rec (⌜ x ⌝ ∷ ⌜ e ⌝ ∷ []) ∎
⌜⌜⌝⌝E≡⌜⌝′ (var x) =
⌜ var x ⌝ ∎
⌜⌜⌝⌝E≡⌜⌝′ (const c es) =
Exp.const c-const (⌜ c ⌝ ∷ ⟨ ⌜ ⌜ es ⌝ ⌝E⋆ ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E⋆≡⌜⌝ es) ⟩∎
const c-const (⌜ c ⌝ ∷ ⌜ es ⌝ ∷ []) ∎
⌜⌜⌝⌝B≡⌜⌝ : (b : Br) → ⌜ ⌜ b ⌝ ⌝B ≡ ⌜ b ⌝
⌜⌜⌝⌝B≡⌜⌝ (branch c xs e) =
Exp.const c-branch (⌜ c ⌝ ∷ ⌜ xs ⌝ ∷ ⟨ ⌜ ⌜ e ⌝ ⌝E ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e) ⟩∎
const c-branch (⌜ c ⌝ ∷ ⌜ xs ⌝ ∷ ⌜ e ⌝ ∷ []) ∎
⌜⌜⌝⌝E⋆≡⌜⌝ : (es : List Exp) → ⌜ ⌜ es ⌝ ⌝E⋆ ≡ ⌜ es ⌝
⌜⌜⌝⌝E⋆≡⌜⌝ es = ⌜⌜⌝⌝E⋆≡⌜⌝′ es
where
⌜⌜⌝⌝E⋆≡⌜⌝′ : (es : List Exp) → ⌜ ⌜ es ⌝ ⌝E⋆ ≡ ⌜ es ⌝
⌜⌜⌝⌝E⋆≡⌜⌝′ [] =
⌜ [] ⦂ List Exp ⌝ ∎
⌜⌜⌝⌝E⋆≡⌜⌝′ (e ∷ es) =
Exp.const c-cons (⟨ ⌜ ⌜ e ⌝ ⌝E ⟩ ∷ ⌜ ⌜ es ⌝ ⌝E⋆ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E≡⌜⌝ e) ⟩
const c-cons (⌜ e ⌝ ∷ ⟨ ⌜ ⌜ es ⌝ ⌝E⋆ ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝E⋆≡⌜⌝ es) ⟩∎
const c-cons (⌜ e ⌝ ∷ ⌜ es ⌝ ∷ []) ∎
⌜⌜⌝⌝B⋆≡⌜⌝ : (bs : List Br) → ⌜ ⌜ bs ⌝ ⌝B⋆ ≡ ⌜ bs ⌝
⌜⌜⌝⌝B⋆≡⌜⌝ bs = ⌜⌜⌝⌝B⋆≡⌜⌝′ bs
where
⌜⌜⌝⌝B⋆≡⌜⌝′ : (bs : List Br) → ⌜ ⌜ bs ⌝ ⌝B⋆ ≡ ⌜ bs ⌝
⌜⌜⌝⌝B⋆≡⌜⌝′ [] =
⌜ [] ⦂ List Br ⌝ ∎
⌜⌜⌝⌝B⋆≡⌜⌝′ (b ∷ bs) =
Exp.const c-cons (⟨ ⌜ ⌜ b ⌝ ⌝B ⟩ ∷ ⌜ ⌜ bs ⌝ ⌝B⋆ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝B≡⌜⌝ b) ⟩
const c-cons (⌜ b ⌝ ∷ ⟨ ⌜ ⌜ bs ⌝ ⌝B⋆ ⟩ ∷ []) ≡⟨ ⟨by⟩ (⌜⌜⌝⌝B⋆≡⌜⌝ bs) ⟩∎
const c-cons (⌜ b ⌝ ∷ ⌜ bs ⌝ ∷ []) ∎