Source code on Github
{-# OPTIONS --safe --without-K #-}
module Reflection.Utils.Goal where
open import Meta.Prelude
open import Reflection
open import Reflection.AST.Argument
open import Reflection.Utils.Args using (getVisibleArgs)
open import Reflection.Utils.Metas using (isMeta; findMetaIds; firstMeta; shareMeta)
import Data.Vec as Vec
open import Data.List using (null)
underPis : ℕ → Type → (ℕ → Type → TC Term) → TC Term
underPis = go 0
where
go : ℕ → ℕ → Type → (ℕ → Type → TC Term) → TC Term
go n 0 ty k = k n ty
go n (suc fuel) ty k = do
ty' ← reduce ty
case ty' of λ where
(pi a@(arg (arg-info av _) dom) (abs s b)) → do
case firstMeta dom of λ where
(just m) → blockOnMeta m
nothing → pure tt
body ← extendContext s a (go (suc n) fuel b k)
pure (lam av (abs s body))
t → k n t
equationSides : Term → Maybe (Term × Term)
equationSides t = case getVisibleArgs 2 t of λ where
(just (lhs Vec.∷ rhs Vec.∷ Vec.[])) → just (lhs , rhs)
_ → nothing
requireEquationSides : Term → TC (Term × Term)
requireEquationSides t = case equationSides t of λ where
(just p) → pure p
nothing → typeError
( strErr "Malformed call to algebraic solver. "
∷ strErr "Expected target type to be of shape LHS ≈ RHS. "
∷ strErr "Instead: "
∷ termErr t
∷ [])
blockOnEquationMetas : String → (equation lhs rhs : Term) → TC ⊤
blockOnEquationMetas macroName equation lhs rhs = do
let bothStructured = not (isMeta lhs) ∧ not (isMeta rhs)
let metasL = findMetaIds lhs
let metasR = findMetaIds rhs
let anyMetas = not (null metasL ∧ null metasR)
let sharedMeta = shareMeta metasL metasR
if bothStructured ∧ anyMetas ∧ not sharedMeta
then typeError
( strErr macroName
∷ strErr ": the goal `LHS ≈ RHS` has at least one side "
∷ strErr "containing a metavariable that could not be resolved. To run this "
∷ strErr "solver you must add type annotations to resolve these variables."
∷ [])
else pure tt
case firstMeta equation of λ where
(just m) → blockOnMeta m
nothing → pure tt