{-# OPTIONS --safe #-}
module Tactic.Premises where
open import Prelude hiding (Type)
open import PreludeMeta
open import MetaPrelude using (enumerate)
import Data.List as L
open import Data.Fin using (toℕ)
open import Class.Show
open import Class.Foldable
open import Interface.STS
open Debug ("tactic.premises", 100)
open import Reflection.Ext
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 ← map 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
let whitelist = Interface.STS._∙_
`∷ Interface.STS.∙_
`∷ Interface.STS._────────────────────────────────_
`∷ Interface.STS.────────────────────────────────_
`∷ Interface.STS._───────────────────────────────────────_
`∷ Interface.STS.───────────────────────────────────────_
`∷ []
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 = fold where instance _ = Monoid-Term-×; _ = Semigroup-Term-×
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₁
_ = 𝕢ˡ , 𝕢ʳ