101 lines
3.5 KiB
Plaintext
101 lines
3.5 KiB
Plaintext
|
import LSpec
|
|||
|
import Lean
|
|||
|
import Test.Common
|
|||
|
|
|||
|
open Lean
|
|||
|
open Pantograph
|
|||
|
|
|||
|
namespace Pantograph.Test.Tactic.NoConfuse
|
|||
|
|
|||
|
def valueAndType (recursor: String): MetaM (Expr × Expr) := do
|
|||
|
let recursor ← match Parser.runParserCategory
|
|||
|
(env := ← MonadEnv.getEnv)
|
|||
|
(catName := `term)
|
|||
|
(input := recursor)
|
|||
|
(fileName := filename) with
|
|||
|
| .ok syn => pure syn
|
|||
|
| .error error => throwError "Failed to parse: {error}"
|
|||
|
runTermElabMInMeta do
|
|||
|
let recursor ← Elab.Term.elabTerm (stx := recursor) .none
|
|||
|
let recursorType ← Meta.inferType recursor
|
|||
|
return (recursor, recursorType)
|
|||
|
|
|||
|
def test_nat (env: Environment): IO LSpec.TestSeq :=
|
|||
|
let expr := "λ (n: Nat) (h: 0 = n + 1) => False"
|
|||
|
runMetaMSeq env do
|
|||
|
let (expr, exprType) ← valueAndType expr
|
|||
|
Meta.lambdaTelescope expr $ λ _ body => do
|
|||
|
let recursor ← match Parser.runParserCategory
|
|||
|
(env := ← MonadEnv.getEnv)
|
|||
|
(catName := `term)
|
|||
|
(input := "h")
|
|||
|
(fileName := filename) with
|
|||
|
| .ok syn => pure syn
|
|||
|
| .error error => throwError "Failed to parse: {error}"
|
|||
|
let mut tests := LSpec.TestSeq.done
|
|||
|
-- Apply the tactic
|
|||
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|||
|
let tactic := Tactic.noConfuse recursor
|
|||
|
let test ← runTermElabMInMeta do
|
|||
|
let newGoals ← runTacticOnMVar tactic target.mvarId!
|
|||
|
pure $ LSpec.check "goals" ((← newGoals.mapM (λ g => do exprToStr (← g.getType))) =
|
|||
|
[])
|
|||
|
tests := tests ++ test
|
|||
|
return tests
|
|||
|
|
|||
|
def test_nat_fail (env: Environment): IO LSpec.TestSeq :=
|
|||
|
let expr := "λ (n: Nat) (h: n = n) => False"
|
|||
|
runMetaMSeq env do
|
|||
|
let (expr, _) ← valueAndType expr
|
|||
|
Meta.lambdaTelescope expr $ λ _ body => do
|
|||
|
let recursor ← match Parser.runParserCategory
|
|||
|
(env := ← MonadEnv.getEnv)
|
|||
|
(catName := `term)
|
|||
|
(input := "h")
|
|||
|
(fileName := filename) with
|
|||
|
| .ok syn => pure syn
|
|||
|
| .error error => throwError "Failed to parse: {error}"
|
|||
|
let mut tests := LSpec.TestSeq.done
|
|||
|
-- Apply the tactic
|
|||
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|||
|
try
|
|||
|
let tactic := Tactic.noConfuse recursor
|
|||
|
let _ ← runTermElabMInMeta $ runTacticOnMVar tactic target.mvarId!
|
|||
|
tests := tests ++ assertUnreachable "Tactic should fail"
|
|||
|
catch _ =>
|
|||
|
tests := tests ++ LSpec.check "Tactic should fail" true
|
|||
|
return tests
|
|||
|
return tests
|
|||
|
|
|||
|
def test_list (env: Environment): IO LSpec.TestSeq :=
|
|||
|
let expr := "λ (l: List Nat) (h: [] = 1 :: l) => False"
|
|||
|
runMetaMSeq env do
|
|||
|
let (expr, exprType) ← valueAndType expr
|
|||
|
Meta.lambdaTelescope expr $ λ _ body => do
|
|||
|
let recursor ← match Parser.runParserCategory
|
|||
|
(env := ← MonadEnv.getEnv)
|
|||
|
(catName := `term)
|
|||
|
(input := "h")
|
|||
|
(fileName := filename) with
|
|||
|
| .ok syn => pure syn
|
|||
|
| .error error => throwError "Failed to parse: {error}"
|
|||
|
let mut tests := LSpec.TestSeq.done
|
|||
|
-- Apply the tactic
|
|||
|
let target ← Meta.mkFreshExprSyntheticOpaqueMVar body
|
|||
|
let tactic := Tactic.noConfuse recursor
|
|||
|
let test ← runTermElabMInMeta do
|
|||
|
let newGoals ← runTacticOnMVar tactic target.mvarId!
|
|||
|
pure $ LSpec.check "goals" ((← newGoals.mapM (λ g => do exprToStr (← g.getType))) =
|
|||
|
[])
|
|||
|
tests := tests ++ test
|
|||
|
return tests
|
|||
|
|
|||
|
def suite (env: Environment): List (String × IO LSpec.TestSeq) :=
|
|||
|
[
|
|||
|
("nat", test_nat env),
|
|||
|
("nat_fail", test_nat_fail env),
|
|||
|
("list", test_list env),
|
|||
|
]
|
|||
|
|
|||
|
end Pantograph.Test.Tactic.NoConfuse
|