2024-04-20 13:09:41 -07:00
|
|
|
|
import LSpec
|
|
|
|
|
import Lean
|
2024-04-22 00:11:41 -07:00
|
|
|
|
import Test.Common
|
2024-04-20 13:09:41 -07:00
|
|
|
|
|
|
|
|
|
open Lean
|
2024-04-22 00:11:41 -07:00
|
|
|
|
open Pantograph
|
2024-04-20 13:09:41 -07:00
|
|
|
|
|
|
|
|
|
namespace Pantograph.Test.Tactic.MotivatedApply
|
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
def test_type_extract : TestT Elab.TermElabM Unit := do
|
|
|
|
|
let recursor ← parseSentence "@Nat.brecOn"
|
|
|
|
|
let recursorType ← Meta.inferType recursor
|
|
|
|
|
addTest $ LSpec.check "recursorType" ("{motive : Nat → Sort ?u.1} → (t : Nat) → ((t : Nat) → Nat.below t → motive t) → motive t" =
|
|
|
|
|
(← exprToStr recursorType))
|
|
|
|
|
let info ← match Tactic.getRecursorInformation recursorType with
|
|
|
|
|
| .some info => pure info
|
|
|
|
|
| .none => throwError "Failed to extract recursor info"
|
|
|
|
|
addTest $ LSpec.check "iMotive" (info.iMotive = 2)
|
|
|
|
|
let motiveType := info.getMotiveType
|
|
|
|
|
addTest $ LSpec.check "motiveType" ("Nat → Sort ?u.1" =
|
|
|
|
|
(← exprToStr motiveType))
|
2024-04-22 00:11:41 -07:00
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
def test_nat_brec_on : TestT Elab.TermElabM Unit := do
|
2024-04-22 00:11:41 -07:00
|
|
|
|
let expr := "λ (n t: Nat) => n + 0 = n"
|
2024-06-27 11:34:21 -07:00
|
|
|
|
let expr ← parseSentence expr
|
|
|
|
|
Meta.lambdaTelescope expr $ λ _ body => do
|
|
|
|
|
let recursor ← match Parser.runParserCategory
|
|
|
|
|
(env := ← MonadEnv.getEnv)
|
|
|
|
|
(catName := `term)
|
|
|
|
|
(input := "@Nat.brecOn")
|
|
|
|
|
(fileName := filename) with
|
|
|
|
|
| .ok syn => pure syn
|
|
|
|
|
| .error error => throwError "Failed to parse: {error}"
|
|
|
|
|
-- Apply the tactic
|
|
|
|
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|
|
|
|
let tactic := Tactic.motivatedApply recursor
|
|
|
|
|
let newGoals ← runTacticOnMVar tactic target.mvarId!
|
|
|
|
|
let test := LSpec.check "goals" ((← newGoals.mapM (λ g => do exprToStr (← g.getType))) =
|
|
|
|
|
[
|
|
|
|
|
"Nat → Prop",
|
|
|
|
|
"Nat",
|
|
|
|
|
"∀ (t : Nat), Nat.below t → ?motive t",
|
|
|
|
|
"?motive ?m.67 = (n + 0 = n)",
|
|
|
|
|
])
|
|
|
|
|
addTest test
|
2024-04-22 00:11:41 -07:00
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
def test_list_brec_on : TestT Elab.TermElabM Unit := do
|
2024-05-05 10:36:43 -07:00
|
|
|
|
let expr := "λ {α : Type} (l: List α) => l ++ [] = [] ++ l"
|
2024-06-27 11:34:21 -07:00
|
|
|
|
let expr ← parseSentence expr
|
|
|
|
|
Meta.lambdaTelescope expr $ λ _ body => do
|
2024-05-11 20:01:02 -07:00
|
|
|
|
let recursor ← match Parser.runParserCategory
|
|
|
|
|
(env := ← MonadEnv.getEnv)
|
|
|
|
|
(catName := `term)
|
2024-06-27 11:34:21 -07:00
|
|
|
|
(input := "@List.brecOn")
|
2024-05-11 20:01:02 -07:00
|
|
|
|
(fileName := filename) with
|
|
|
|
|
| .ok syn => pure syn
|
|
|
|
|
| .error error => throwError "Failed to parse: {error}"
|
2024-06-27 11:34:21 -07:00
|
|
|
|
-- Apply the tactic
|
|
|
|
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|
|
|
|
let tactic := Tactic.motivatedApply recursor
|
|
|
|
|
let newGoals ← runTacticOnMVar tactic target.mvarId!
|
|
|
|
|
addTest $ LSpec.check "goals" ((← newGoals.mapM (λ g => do exprToStr (← g.getType))) =
|
|
|
|
|
[
|
|
|
|
|
"Type ?u.90",
|
|
|
|
|
"List ?m.92 → Prop",
|
|
|
|
|
"List ?m.92",
|
|
|
|
|
"∀ (t : List ?m.92), List.below t → ?motive t",
|
|
|
|
|
"?motive ?m.94 = (l ++ [] = [] ++ l)",
|
|
|
|
|
])
|
2024-05-11 20:01:02 -07:00
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
def test_partial_motive_instantiation : TestT Elab.TermElabM Unit := do
|
|
|
|
|
let expr := "λ (n t: Nat) => n + 0 = n"
|
|
|
|
|
let recursor ← match Parser.runParserCategory
|
|
|
|
|
(env := ← MonadEnv.getEnv)
|
|
|
|
|
(catName := `term)
|
|
|
|
|
(input := "@Nat.brecOn")
|
|
|
|
|
(fileName := filename) with
|
|
|
|
|
| .ok syn => pure syn
|
|
|
|
|
| .error error => throwError "Failed to parse: {error}"
|
|
|
|
|
let expr ← parseSentence expr
|
|
|
|
|
Meta.lambdaTelescope expr $ λ _ body => do
|
|
|
|
|
-- Apply the tactic
|
|
|
|
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|
|
|
|
let tactic := Tactic.motivatedApply recursor
|
|
|
|
|
let newGoals ← runTacticOnMVar tactic target.mvarId!
|
|
|
|
|
let majorId := 67
|
|
|
|
|
addTest $ (LSpec.check "goals" ((← newGoals.mapM (λ g => do exprToStr (← g.getType))) =
|
|
|
|
|
[
|
|
|
|
|
"Nat → Prop",
|
|
|
|
|
"Nat",
|
|
|
|
|
"∀ (t : Nat), Nat.below t → ?motive t",
|
|
|
|
|
s!"?motive ?m.{majorId} = (n + 0 = n)",
|
|
|
|
|
]))
|
|
|
|
|
let [motive, major, step, conduit] := newGoals | panic! "Incorrect goal number"
|
|
|
|
|
addTest $ (LSpec.check "goal name" (major.name.toString = s!"_uniq.{majorId}"))
|
2024-05-11 20:01:02 -07:00
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
-- Assign motive to `λ x => x + _`
|
|
|
|
|
let motive_assign ← parseSentence "λ (x: Nat) => @Nat.add x + 0 = _"
|
|
|
|
|
motive.assign motive_assign
|
2024-05-11 20:01:02 -07:00
|
|
|
|
|
2024-06-27 11:34:21 -07:00
|
|
|
|
addTest $ ← conduit.withContext do
|
|
|
|
|
let t := toString (← Meta.ppExpr $ ← conduit.getType)
|
|
|
|
|
return LSpec.check "conduit" (t = s!"(?m.{majorId}.add + 0 = ?m.138 ?m.{majorId}) = (n + 0 = n)")
|
2024-05-05 10:36:43 -07:00
|
|
|
|
|
2024-04-20 13:09:41 -07:00
|
|
|
|
def suite (env: Environment): List (String × IO LSpec.TestSeq) :=
|
2024-04-22 00:11:41 -07:00
|
|
|
|
[
|
2024-06-27 11:34:21 -07:00
|
|
|
|
("type_extract", test_type_extract),
|
|
|
|
|
("Nat.brecOn", test_nat_brec_on),
|
|
|
|
|
("List.brecOn", test_list_brec_on),
|
|
|
|
|
("Nat.brecOn partial motive instantiation", test_partial_motive_instantiation),
|
|
|
|
|
] |>.map (λ (name, t) => (name, runTestTermElabM env t))
|
2024-04-20 13:09:41 -07:00
|
|
|
|
|
|
|
|
|
end Pantograph.Test.Tactic.MotivatedApply
|