open import Syntax.Simple.Signature module Syntax.Simple.Unif (D : SigD) where open import Prelude open import Syntax.Simple.Term D open import Syntax.Simple.Properties D private variable A : Set Ξ Θ m n l : ℕ x : Fin Ξ xs ys : Fins# Ξ open ≡-Reasoning open Equivalence insert : (x : Fin Ξ) (t : Tm 0) (ρ : ∃Sub⊆ Ξ) → MinDec (Ext ρ (` x ≈ t)) insert x t (xs , ρ) with fresh? x xs ... | inl x#xs = yesₘ (_ , extend ρ x#xs t) record { proof = record { ext = record { domain-ext = there ; consistency = λ _ → refl } ; witness = (λ { (here eq) → here eq }) , refl } ; minimality = λ where σ (ext-con (≤-con xs⊆ys con) (x∈zs , eq)) → record { domain-ext = λ where (here refl) → x∈zs (here refl) (there y∈) → xs⊆ys y∈ ; consistency = λ where (here refl) → sym eq (there x∈) → con x∈ } } ... | inr x∈xs with ρ x∈xs ≟ t ... | yes eq = yesₘ (_ , ρ) (Pρ→MinExtP ((λ { (here refl) → x∈xs }) , eq)) ... | no neq = noₘ λ where (zs , σ) (ext-con (≤-con xs⊆zs con) (x∈zs , eq)) → neq (begin ρ x∈xs ≡⟨ con x∈xs ⟩ σ (xs⊆zs x∈xs) ≡⟨ cong σ (#∈-uniq _ _) ⟩ σ (x∈zs (here refl)) ≡⟨ eq ⟩ t ∎) mutual acmp : (t : Tm Ξ) (u : Tm 0) (ρ : ∃Sub⊆ Ξ) → MinDec (Ext ρ (t ≈ u)) acmp (` x) t ρ = insert x t ρ acmp (op (i , ts)) (op (j , us)) ρ with i ≟ j ... | no i≠j = noₘ λ where σ (ext-con ρ≤σ (_ , refl)) → i≠j refl ... | yes refl = MinDec⇔ (Ext⇔ (ts≈us⇔opts≈opus ts us) ρ) .to (acmpⁿ ts us ρ) acmpⁿ : (ts : Tm Ξ ^ n) (us : Tm 0 ^ n) (ρ : ∃Sub⊆ Ξ) → MinDec (Ext ρ (ts ≈ⁿ us)) acmpⁿ [] [] ρ = yesₘ ρ (Pρ→MinExtP ((λ ()) , refl)) acmpⁿ (t ∷ ts) (u ∷ us) ρ with acmpⁿ ts us ρ ... | noₘ ¬σ = noₘ λ σ (ext-con ρ≤σ (t∷ts⊆ , eq)) → ¬σ σ (ext-con ρ≤σ ((λ x∈ → t∷ts⊆ (∪⁺ʳ (vars t) x∈)) , V.∷-injectiveʳ eq)) ... | yesₘ ρ̅ minρ̅ with acmp t u ρ̅ ... | noₘ ¬Ext = noₘ (λ σ Qσ → failure-propagate ρ ρ̅ minρ̅ ¬Ext σ (Ext⇔ (t≈u×ts≈us⇔tts≈uus t u ts us) ρ σ .from Qσ)) ... | yesₘ ρ′ minρ′ = yesₘ ρ′ (Min⇔ (Ext⇔ (t≈u×ts≈us⇔tts≈uus t u ts us) ρ) ρ′ .to (optimist ρ ρ̅ ρ′ (↑≈ⁿ ts us) minρ̅ minρ′)) cmp : (t : Tm Ξ) (u : Tm 0) → MinDec (t ≈ u) cmp t u = MinDecExt∅⇔MinDec .to (acmp t u empty)