{-# OPTIONS --without-K --safe #-}
module Fragment.Tactic.Utils where
open import Reflection hiding (name; Type; _≟_)
open import Reflection.Term using (_≟_)
open import Data.Nat using (ℕ; zero; suc)
open import Data.Fin using (Fin)
open import Data.Nat.Show using (show)
open import Data.String using (String) renaming (_++_ to _⟨S⟩_)
open import Data.List using (List; []; _∷_; _++_; drop; take; reverse)
open import Data.Vec using (Vec; []; _∷_; map; toList)
open import Data.Bool using (Bool; true; false; if_then_else_)
open import Data.Maybe using (Maybe; nothing; just)
open import Data.Product using (_×_; _,_)
open import Relation.Nullary using (yes; no; _because_)
open import Relation.Binary.PropositionalEquality as PE using (_≡_)
vra : ∀ {a} {A : Set a} → A → Arg A
vra = arg (arg-info visible relevant)
hra : ∀ {a} {A : Set a} → A → Arg A
hra = arg (arg-info hidden relevant)
infixr 5 λ⦅_⦆→_ λ⦃_⦄→_
λ⦅_⦆→_ : String → Term → Term
λ⦅ x ⦆→ body = lam visible (abs x body)
λ⦃_⦄→_ : String → Term → Term
λ⦃ x ⦄→ body = lam hidden (abs x body)
constructors : Definition → List Name
constructors (data-type _ cs) = cs
constructors _ = []
apply : Term → List (Arg Term) → Term
apply (var x xs) args = var x (xs ++ args)
apply (con x xs) args = con x (xs ++ args)
apply (def x xs) args = def x (xs ++ args)
apply (meta x xs) args = meta x (xs ++ args)
apply (pat-lam cs xs) args = pat-lam cs (xs ++ args)
apply x _ = x
prod : ∀ {a} {A : Set a} → ℕ → List A → List A
prod n xs = reverse (drop n (reverse xs))
ekat : ∀ {a} {A : Set a} → ℕ → List A → List A
ekat n xs = reverse (take n (reverse xs))
find : ∀ {a} {A : Set a} → (A → TC Bool) → List A → TC (Maybe A)
find p [] = return nothing
find p (x ∷ xs)
= do p? ← p x
if p? then return (just x)
else find p xs
mapList : ∀ {a b} {A : Set a} {B : Set b}
→ List (A → B) → List A → List B
mapList [] _ = []
mapList _ [] = []
mapList (f ∷ fs) (x ∷ xs) = f x ∷ mapList fs xs
unapply : Term → ℕ → Term
unapply (var x args) n = var x (prod n args)
unapply (con x args) n = con x (prod n args)
unapply (def x args) n = def x (prod n args)
unapply (meta x args) n = meta x (prod n args)
unapply (pat-lam cs args) n = pat-lam cs (prod n args)
unapply x _ = x
equalTypes : Term → Term → Bool
equalTypes τ τ' with τ ≟ τ'
... | yes _ = true
... | _ = false
flatten : ∀ {a} {A : Set a} → TC (TC A) → TC A
flatten x
= do x' ← x
x'
listTC : ∀ {a} {A : Set a} → List (TC A) → TC (List A)
listTC [] = return []
listTC (x ∷ xs)
= do x' ← x
xs' ← listTC xs
return (x' ∷ xs')
n-ary : ∀ (n : ℕ) → Term → Term
n-ary zero body = body
n-ary (suc n) body = λ⦅ "x" ⟨S⟩ show n ⦆→ (n-ary n body)
debrujin : ∀ (n : ℕ) → Vec Term n
debrujin zero = []
debrujin (suc n) = (var n []) ∷ debrujin n
η-convert : ∀ (n : ℕ) → Term → TC Term
η-convert n t = runSpeculative inner
where inner : TC (Term × Bool)
inner
= do t ← normalise (n-ary n (apply t (toList (map vra (debrujin n)))))
return (t , false)
prefix : ℕ → Term → Term → TC Bool
prefix n x y
= do y ← catchTC (η-convert n (unapply y n)) (return y)
let (b because _) = x ≟ y
return b
extract-type-arg : Term → TC Term
extract-type-arg (pi (arg _ x) _) = return x
extract-type-arg x = typeError (termErr x ∷ strErr "isn't a pi type" ∷ [])
extract-name : Term → TC Name
extract-name (def x _) = return x
extract-name x = typeError (termErr x ∷ strErr "isn't an application of a definition" ∷ [])
extract-definition : Term → TC Definition
extract-definition x
= do x' ← normalise x
η ← extract-name x'
getDefinition η
extract-constructors : Term → TC (List Name)
extract-constructors x
= do δ ← extract-definition x
return (constructors δ)
fin : ℕ → Term
fin zero = con (quote Fin.zero) []
fin (suc n) = con (quote Fin.suc) (vra (fin n) ∷ [])
vec : ∀ {n : ℕ} → Vec Term n → Term
vec [] = con (quote Vec.[]) []
vec (x ∷ xs) = con (quote Vec._∷_) (vra x ∷ vra (vec xs) ∷ [])
vec-len : Term → TC ℕ
vec-len (def (quote Vec) (_ ∷ _ ∷ (arg _ n) ∷ [])) = unquoteTC n
vec-len t = typeError (termErr t ∷ strErr "isn't a" ∷ nameErr (quote Vec) ∷ [])
panic : ∀ {a} {A : Set a} → Term → TC A
panic x = typeError (termErr x ∷ [])
strip-telescope : Term → TC (Term × List (Arg String))
strip-telescope (pi (vArg _) (abs s x))
= do (τ , acc) ← strip-telescope x
return (τ , vra s ∷ acc)
strip-telescope (pi (hArg _) (abs s x))
= do (τ , acc) ← strip-telescope x
return (τ , hra s ∷ acc)
strip-telescope (pi _ _) =
typeError (strErr "no support for irrelevant goals" ∷ [])
strip-telescope t = return (t , [])
restore-telescope : List (Arg String) → Term → TC Term
restore-telescope [] t = return t
restore-telescope (vArg x ∷ xs) t
= do t ← restore-telescope xs t
return (λ⦅ x ⦆→ t)
restore-telescope (hArg x ∷ xs) t
= do t ← restore-telescope xs t
return (λ⦃ x ⦄→ t)
restore-telescope (_ ∷ _) _ =
typeError (strErr "no support for irrelevant goals" ∷ [])
hasType : Term → Term → TC Bool
hasType τ t = runSpeculative inner
where inner = do τ' ← inferType t
return (equalTypes τ τ' , false)
insert : List Term → Term → List Term
insert [] n = n ∷ []
insert (x ∷ xs) n with x ≟ n
... | yes _ = x ∷ xs
... | no _ = x ∷ insert xs n
indexOf : List Term → Term → Maybe ℕ
indexOf [] t = nothing
indexOf (x ∷ xs) t with x ≟ t | indexOf xs t
... | yes _ | _ = just 0
... | no _ | just n = just (suc n)
... | no _ | nothing = nothing