\import Data.Fin
\import Logic
\import Paths
\import Paths.Meta
\class SolverModel (M : \Set) {
| \protected Term : Nat -> \Set
| \protected NF : Nat -> \Set
| \protected normalize {n : Nat} : Term n -> NF n
| \protected interpret {n : Nat} (env : Fin n -> M) : Term n -> M
| \protected interpretNF {n : Nat} (env : Fin n -> M) : NF n -> M
| \protected interpretNF-consistent {n : Nat} {env : Fin n -> M} {t : Term n} : interpretNF env (normalize t) = interpret env t
\protected \lemma terms-equality (env : Array M) (t s : Term env.len) (p : interpretNF env (normalize t) = interpretNF env (normalize s)) : interpret env t = interpret env s
=> inv interpretNF-consistent *> p *> interpretNF-consistent
\protected \lemma terms-equality-conv (env : Array M) (t s : Term env.len) (p : interpret env t = interpret env s) : interpretNF env (normalize t) = interpretNF env (normalize s)
=> interpretNF-consistent *> p *> inv interpretNF-consistent
}
\class SubstSolverModel \extends SolverModel {
| \protected nfVar {n : Nat} : Fin n -> NF n
| \protected \infixl 2 >>= {m n : Nat} : NF m -> (Fin m -> NF n) -> NF n
| \protected >>=-consistent {m n : Nat} {env : Fin n -> M} {nf : NF m} {k : Fin m -> NF n}
: interpretNF env (nf >>= k) = interpretNF (\lam v => interpretNF env (k v)) nf
\lemma apply-axiom (env : Array M) (t s : Term env.len) (p : interpret env t = interpret env s) (pattern : NF (suc env.len)) : interpretNF env (pattern >>= fcase (normalize t) nfVar) = interpretNF env (pattern >>= fcase (normalize s) nfVar)
=> >>=-consistent *> pmap (interpretNF __ pattern) (ext \case \elim __ \with {
| 0 => terms-equality-conv env t s p
| suc v => idp
}) *> inv >>=-consistent
}