{-# OPTIONS --safe #-}
module Prelude.STS.GenPremises where
open import Prelude.Init
hiding (Type; pred; _∷_)
renaming (_∈_ to _∈ˡ_)
open import Prelude.InferenceRules
open import Class.Show
open import Class.Foldable
open import Class.Decidable
open import Class.DecEq.Instances
open import Class.Monad
open import Class.Functor
open import Class.Semigroup
open import Meta.Init
renaming (TC to TCI)
hiding (Monad-TC; MonadError-TC)
open import Agda.Builtin.Reflection
using (withReduceDefs)
open import Reflection
using (TC; Name; Meta; extendContext; withNormalisation)
open import Reflection.Utils
hiding (mkRecord)
open import Reflection.Debug
open import Reflection.Utils.Debug
hiding (error)
open import Class.MonadTC
hiding (extendContext)
open MonadTC ⦃...⦄
open import Class.MonadError
using (MonadError; MonadError-TC)
open MonadError ⦃...⦄
using (error; catch)
open import Meta.Prelude
open Debug ("tactic.premises", 100)
open import Reflection using ()
open import Data.List using (_∷_; [])
instance
iTC = MonadTC-TC
iTCE = MonadError-TC
extendContextTel : Telescope → TC A → TC A
extendContextTel = λ where
[] → id
((x , t) ∷ tel) → extendContext x t ∘ extendContextTel tel
reduceDef : Type → TC Type
reduceDef = λ where
t@(def _ _) → reduce t
t → return t
macro
infixr 4 _`∷_
_`∷_ : Name → List Name → Hole → TC ⊤
(x `∷ y) hole = do
`x ← quoteTC x
`y ← quoteTC y
unify hole $ con (quote _∷_) (vArg `x ∷ vArg `y ∷ [])
freeVars : Term → List ℕ
freeVars = go 0 where mutual
go : ℕ → Term → _
go bound = λ where
(var x as) → if bound Nat.≤ᵇ x then [ x ∸ bound ] else []
(def _ as) → goArgs bound as
(con _ as) → goArgs bound as
(lam _ t̂) → goAbs (suc bound) t̂
(pat-lam cs as) → goCls bound cs ++ goArgs bound as
(pi at t̂) → goArg bound at ++ goAbs (suc bound) t̂
(meta _ as) → goArgs bound as
_ → []
goArg : ℕ → Arg Term → _
goArg b (arg _ t) = go b t
goAbs : ℕ → Abs Term → _
goAbs b (abs _ t) = go b t
goArgs : ℕ → Args Term → _
goArgs b = λ where [] → []; (a ∷ as) → goArg b a ++ goArgs b as
goCl : ℕ → Clause → _
goCl b = λ where
(clause tel _ t) → go (length tel + b) t
(absurd-clause _ _) → []
goCls : ℕ → List Clause → _
goCls b = λ where [] → []; (c ∷ cs) → goCl b c ++ goCls b cs
module _ x y z where
_ = freeVars (quoteTerm (λ x → x + 1))
≡ []
∋ refl
_ = freeVars (quoteTerm (λ x → x + y))
≡ [ 1 ]
∋ refl
_ = freeVars (quoteTerm (λ x y → x + y + z))
≡ [ 0 ]
∋ refl
_ = freeVars (quoteTerm (λ x → x + y + z))
≡ (1 ∷ 0 ∷ [])
∋ refl
_ = freeVars (quoteTerm (x + y + z))
≡ (2 ∷ 1 ∷ 0 ∷ [])
∋ refl
_ = freeVars (quote _,_ ◆⟦ ♯ 0 ∣ `λ "y" ⇒ ♯ 1 ⟧)
≡ (0 ∷ 0 ∷ [])
∋ refl
AbsTelescope = List (Abs (Arg Type))
absTelescope : AbsTelescope → Telescope
absTelescope = map λ where (abs x t) → x , t
telescopeAbs : Telescope → AbsTelescope
telescopeAbs = map $ uncurry abs
showAbsTel = show ⦃ Show-Tel ⦄ ∘ absTelescope
hasInstance : Type → TC Bool
hasInstance = isSuccessful ∘ checkType (quote it ∙)
whitelist : List Name
whitelist =
quote _∙_
∷ quote ∙_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────────_
∷ quote _──────────────────────────────────────────────_
∷ quote _─────────────────────────────────────────────_
∷ quote _────────────────────────────────────────────_
∷ quote _───────────────────────────────────────────_
∷ quote _──────────────────────────────────────────_
∷ quote _─────────────────────────────────────────_
∷ quote _────────────────────────────────────────_
∷ quote _───────────────────────────────────────_
∷ quote _──────────────────────────────────────_
∷ quote _─────────────────────────────────────_
∷ quote _────────────────────────────────────_
∷ quote _───────────────────────────────────_
∷ quote _──────────────────────────────────_
∷ quote _─────────────────────────────────_
∷ quote _────────────────────────────────_
∷ quote _───────────────────────────────_
∷ quote _──────────────────────────────_
∷ quote _─────────────────────────────_
∷ quote _────────────────────────────_
∷ quote _───────────────────────────_
∷ quote _──────────────────────────_
∷ quote _─────────────────────────_
∷ quote _────────────────────────_
∷ quote _───────────────────────_
∷ quote _──────────────────────_
∷ quote _─────────────────────_
∷ quote _────────────────────_
∷ quote _───────────────────_
∷ quote _──────────────────_
∷ quote _─────────────────_
∷ quote _────────────────_
∷ quote _───────────────_
∷ quote _──────────────_
∷ quote _─────────────_
∷ quote _────────────_
∷ quote _───────────_
∷ quote _──────────_
∷ quote _─────────_
∷ quote _────────_
∷ quote _───────_
∷ quote _──────_
∷ quote _─────_
∷ quote _────_
∷ quote _───_
∷ []
genPremises : Name → Name → TC ⊤
genPremises f n = do
print $ "*** Generating premises for constructor:" <+> show n <+> "***"
ty ← reduceRuleSyntax =<< getType n
let is , hs = breakImplicits $ viewTy ty .proj₁
hs ← fmap unbundleHypotheses
$ extendContextTel (absTelescope is)
$ mapM reduceRuleSyntax hs
dhs ← filterM (isDecidable? is) hs
let dhs = bundleHypotheses dhs
is , premise ← removeUnusedImplicits is dhs
let premiseTy = tyView (is , quote ∃⁇ ∙)
premiseTel = absTelescope is
premisePs = map (λ (i , x) → arg (argInfo $ unAbs x) (` i))
(uncurry L.zip $ map₁ reverse $ unzip $ enumerate is)
∃premise? = quote _,_ ◆⟦ premise ∣ quote it ∙ ⟧
cl = clause premiseTel premisePs ∃premise?
print $ "```\n" <> show f <+> ":" <+> show premiseTy <> "\n"
declareDef (vArg f) premiseTy
defineFun f [ cl ]
where
reduceRuleSyntax : Type → TC Type
reduceRuleSyntax ty = do
withReduceDefs (true , whitelist) $ normalise ty
breakImplicits : AbsTelescope → AbsTelescope × List Type
breakImplicits = map₂ (unArgs ∘ map unAbs)
∘ break (isVisible? ∘ unAbs)
unbundleHypotheses : List Type → List Type
unbundleHypotheses = concatMap go where go = λ where
(def (quote _×_) (hArg _ ∷ hArg _ ∷ vArg x ∷ vArg ys ∷ [])) →
x ∷ go ys
t → [ t ]
isDecidable? : AbsTelescope → Type → TC Bool
isDecidable? tel ty =
isSuccessful $ checkType (quote it ∙) (tyView (tel , quote _⁇ ∙⟦ ty ⟧))
bundleHypotheses : List Type → Type
bundleHypotheses [] = quote ⊤ ∙
bundleHypotheses (x ∷ []) = x
bundleHypotheses (x ∷ xs) = quote _×_ ∙⟦ x ∣ bundleHypotheses xs ⟧
removeUnusedImplicits : AbsTelescope → Type → TC (AbsTelescope × Type)
removeUnusedImplicits is ty = go (pred $ length is) is ty
where
fvs = freeVars ty
go : ℕ → AbsTelescope → Type → TC (AbsTelescope × Type)
go _ [] t = return ([] , t)
go n (i ∷ is) t =
ifᵈ n ∈ˡ fvs then
map₁ (i ∷_) <$> go (pred n) is t
else
go (pred n) is (mapFreeVars pred n t)
private
data ℝ : ℕ → ℕ → Set where
base :
────────────────────────────────
ℝ 0 0
step : ∀ {n m} →
∙ ℝ n m
────────────────────────────────
ℝ (suc n) (suc m)
module _ ⦃ _ : ℝ ⁇² ⦄ where
unquoteDecl ℝ-base-premises = genPremises ℝ-base-premises (quote ℝ.base)
unquoteDecl ℝ-step-premises = genPremises ℝ-step-premises (quote ℝ.step)
_ : ℝ-base-premises .proj₁
_ = tt
_ : ℝ-base-premises .proj₂ .dec ≡ yes tt
_ = refl
module _ (n m : ℕ) (𝕣 : ℝ n m) where
_ : ℝ-step-premises .proj₁
_ = 𝕣
_ : (ℝ n m) ⁇
_ = ℝ-step-premises .proj₂
open import Class.Monoid
data ℚ {A : Set} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ : A → A → Set where
base :
────────────────────────────────
ℚ ε ε
step : ∀ {n m n′ m′} →
∙ ℚ n m
∙ ℚ n′ m′
────────────────────────────────
ℚ (n ◇ n′) (m ◇ m′)
module _ ⦃ _ : ∀ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ → ℚ {A} ⁇² ⦄ where
unquoteDecl ℚ-base-premises = genPremises ℚ-base-premises (quote ℚ.base)
unquoteDecl ℚ-step-premises = genPremises ℚ-step-premises (quote ℚ.step)
_ : ℚ-base-premises .proj₁
_ = tt
module _ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ (n m n′ m′ : A) (𝕢ˡ : ℚ n m) (𝕢ʳ : ℚ n′ m′) where
_ : ℚ-step-premises .proj₁
_ = 𝕢ˡ , 𝕢ʳ
data ℝ′ : ℕ → ℕ → Set where
base :
────────────────────────────────
ℝ′ 0 0
step : ∀ {n m} {T T′ : ℕ → ℕ} →
∙ ℝ′ n m
∙ T ≡ T′
────────────────────────────────
ℝ′ (suc n) (suc m)
module _ ⦃ _ : ℝ′ ⁇² ⦄ where
unquoteDecl ℝ′-base-premises = genPremises ℝ′-base-premises (quote ℝ′.base)
unquoteDecl ℝ′-step-premises = genPremises ℝ′-step-premises (quote ℝ′.step)
_ : ℝ′-base-premises .proj₁
_ = tt
module _ (n m : ℕ) (𝕣 : ℝ′ n m) where
_ : ℝ′-step-premises .proj₁
_ = 𝕣
module _ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ ⦃ _ : ℚ {A} ⁇² ⦄ ⦃ _ : ℝ ⁇² ⦄ where
data 𝕎 : A → ℕ → Set where
base :
────────────────────────────────
𝕎 ε 0
step : ∀ {x y n n′} →
∙ ℝ n n′
∙ ℚ x y
∙ 𝕎 (x ◇ y) n
────────────────────────────────
𝕎 (x ◇ y) n′
unquoteDecl 𝕎-base-premises = genPremises 𝕎-base-premises (quote 𝕎.base)
_ : 𝕎-base-premises .proj₁
_ = tt
unquoteDecl 𝕎-step-premises = genPremises 𝕎-step-premises (quote 𝕎.step)
module _ (n n′ : ℕ) (x y : A) (𝕣 : ℝ n n′) (𝕢 : ℚ x y) where
_ : 𝕎-step-premises .proj₁
_ = 𝕣 , 𝕢
data 𝕍 {A : Set} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ : A → A → Set where
base :
────────────────────────────────
𝕍 ε ε
step : ∀ {n m n′ m′ z} ⦃ _ : Show A ⦄ →
∙ 𝕍 n m
∙ 𝕍 n′ m′
────────────────────────────────
𝕍 (n ◇ n′ ◇ m ◇ m′) z
module _ ⦃ _ : ∀ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ → 𝕍 {A} ⁇² ⦄ where
unquoteDecl 𝕍-base-premises = genPremises 𝕍-base-premises (quote 𝕍.base)
unquoteDecl 𝕍-step-premises = genPremises 𝕍-step-premises (quote 𝕍.step)
_ : 𝕍-base-premises .proj₁
_ = tt
module _ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄
(n m n′ m′ : A) (𝕢ˡ : 𝕍 n m) (𝕢ʳ : 𝕍 n′ m′) where
_ : 𝕍-step-premises .proj₁
_ = 𝕢ˡ , 𝕢ʳ
data 𝕍′ {A : Set} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ : A → A → Set where
base :
────────────────────────────────
𝕍′ ε ε
step : ∀ {n m n′ m′} ⦃ _ : Show A ⦄ {T : Type} →
∙ 𝕍′ n m
∙ 𝕍′ n′ m′
∙ (∀ T′ → T ≡ T′)
────────────────────────────────
𝕍′ (n ◇ n′) (m ◇ m′)
module _ ⦃ _ : ∀ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ → 𝕍′ {A} ⁇² ⦄ where
unquoteDecl 𝕍′-base-premises = genPremises 𝕍′-base-premises (quote 𝕍′.base)
unquoteDecl 𝕍′-step-premises = genPremises 𝕍′-step-premises (quote 𝕍′.step)
_ : 𝕍′-base-premises .proj₁
_ = tt
module _ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄
(n m n′ m′ : A) (𝕢ˡ : 𝕍′ n m) (𝕢ʳ : 𝕍′ n′ m′) where
_ : 𝕍′-step-premises .proj₁
_ = 𝕢ˡ , 𝕢ˡ
data ℚ′ {A : Set} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ : A → A → Set where
base :
────────────────────────────────
ℚ′ ε ε
step : ∀ {n m n′ m′} ⦃ _ : Show A ⦄ →
∙ ℚ′ n m
∙ ℚ′ n′ m′
────────────────────────────────
ℚ′ (n ◇ n′) (m ◇ m′)
module _ ⦃ _ : ∀ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄ → ℚ′ {A} ⁇² ⦄ where
unquoteDecl ℚ′-base-premises = genPremises ℚ′-base-premises (quote ℚ′.base)
unquoteDecl ℚ′-step-premises = genPremises ℚ′-step-premises (quote ℚ′.step)
_ : ℚ′-base-premises .proj₁
_ = tt
module _ {A} ⦃ _ : Semigroup A ⦄ ⦃ _ : Monoid A ⦄
(n m n′ m′ : A) (𝕢ˡ : ℚ′ n m) (𝕢ʳ : ℚ′ n′ m′) where
_ : ℚ′-step-premises .proj₁
_ = 𝕢ˡ , 𝕢ʳ