{-# 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