Source code on Github{-# OPTIONS --safe --without-K #-}
module Tactic.Constrs where
open import Meta.Prelude
open import Meta.Init
open import Data.List
open import Reflection.Tactic
open import Reflection.Utils
open import Reflection.Utils.TCI
open import Class.Functor.Instances
open import Class.Monad
open import Class.MonadError.Instances
open import Class.MonadReader.Instances
open import Class.MonadTC.Instances
open import Class.Traversable
instance _ = Functor-M ⦃ Class.Monad.Monad-TC ⦄
applyConstrToUnknowns : Name → Type → Term
applyConstrToUnknowns n ty = con n (map toUnknown $ argTys ty)
where
toUnknown : Arg Type → Arg Type
toUnknown (arg i _) = arg i unknown
tryConstrsWith' : ℕ → ITactic → ITactic
tryConstrsWith' zero tac =
inDebugPath "tryConstrs" $ catch tac (λ _ → error1 "Maximum depth reached!")
tryConstrsWith' (suc depth) tac =
inDebugPath "tryConstrs" $ catch tac λ _ → do
inj₁ goal ← reader TCEnv.goal
where _ → error1 "Goal is not a hole!"
goalTy ← inferType goal
debugLog ("Find constructor for type " ∷ᵈ goalTy ∷ᵈ [])
constrs ← getConstrsForTerm goal
try (Data.List.map (λ constr → do
debugLog ("Try constructor " ∷ᵈ proj₁ constr ∷ᵈ " of type: " ∷ᵈ proj₂ constr ∷ᵈ [])
let t = uncurry applyConstrToUnknowns constr
t' ← local (λ env → record env { reconstruction = true }) $ checkType t goalTy
unify goal t'
debugLog1 "Success!"
traverse ⦃ Class.Functor.Instances.Functor-List ⦄ (λ t → runWithHole t (tryConstrsWith' depth tac)) (findMetas t')
return tt)
constrs)
(logAndError1 "No constructors were able to solve the goal!")
module _ ⦃ _ : TCOptions ⦄ where
tryConstrsᵗ : ℕ → Tactic
tryConstrsᵗ n = initTac $ tryConstrsWith' n (error1 "Leaf reached!")
macro
tryConstrsWith = λ n tac → initTac $ tryConstrsWith' n tac
tryConstrs = tryConstrsᵗ
private
module Test where
open import Tactic.Assumption
open import Tactic.Defaults
open import Data.Sum
open import Relation.Binary.PropositionalEquality
startDebug : ⊤
startDebug = byTC (debugLog1 "\n\n\n\nTesting 'tryConstrs'\n")
test₁ : (3 ≡ 3) × (1 + 1 ≡ 2)
test₁ = tryConstrs 2
test₂ : ℕ
test₂ = tryConstrs 2
_ : test₂ ≡ 0
_ = refl
test₃ : (1 ≡ 2) ⊎ (1 ≡ 1)
test₃ = tryConstrs 2
test₄ : ∀ {a} {A : Set a} {x y : A} → x ≡ y → (1 ≡ 2) ⊎ (x ≡ y)
test₄ h = tryConstrsWith 2 assumption'