File size: 5,443 Bytes
0115dcf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | import Pantograph.Library
import Pantograph.Serial
import LSpec
import Test.Common
open Lean
namespace Pantograph.Test.Serial
structure MultiState where
coreContext : Core.Context
env: Environment
abbrev TestM := TestT $ StateRefT MultiState $ IO
instance : MonadEnv TestM where
getEnv := return (β getThe MultiState).env
modifyEnv f := do modifyThe MultiState fun s => { s with env := f s.env }
def runCoreM { Ξ± } (state : Core.State) (testCoreM : TestT CoreM Ξ±) : TestM (Ξ± Γ Core.State) := do
let multiState β getThe MultiState
let coreM := runTestWithResult testCoreM
match β (coreM.run multiState.coreContext state).toBaseIO with
| .error e => do
throw $ .userError $ β e.toMessageData.toString
| .ok ((a, tests), state') => do
set $ (β getThe LSpec.TestSeq) ++ tests
return (a, state')
def test_pickling_environment : TestM Unit := do
let coreSrc : Core.State := { env := β getEnv }
let coreDst : Core.State := { env := β getEnv }
let name := `mystery
IO.FS.withTempFile Ξ» _ envPicklePath => do
let ((), _) β runCoreM coreSrc do
let type: Expr := .forallE `p (.sort 0) (.forallE `h (.bvar 0) (.bvar 1) .default) .default
let value: Expr := .lam `p (.sort 0) (.lam `h (.bvar 0) (.bvar 0) .default) .default
let c := Declaration.defnDecl <| mkDefinitionValEx
(name := name)
(levelParams := [])
(type := type)
(value := value)
(hints := mkReducibilityHintsRegularEx 1)
(safety := .safe)
(all := [])
addDecl c
environmentPickle (β getEnv) envPicklePath
let _ β runCoreM coreDst do
let (env', _) β environmentUnpickle envPicklePath
checkTrue s!"Has symbol {name}" (env'.find? name).isSome
let anotherName := `mystery2
checkTrue s!"Doesn't have symbol {anotherName}" (env'.find? anotherName).isNone
def test_goal_state_simple : TestM Unit := do
let coreSrc : Core.State := { env := β getEnv }
let coreDst : Core.State := { env := β getEnv }
IO.FS.withTempFile Ξ» _ statePath => do
let type: Expr := .forallE `p (.sort 0) (.forallE `h (.bvar 0) (.bvar 1) .default) .default
let stateGenerate : MetaM GoalState := runTermElabMInMeta do
GoalState.create type
let ((), _) β runCoreM coreSrc do
let state β stateGenerate.run'
goalStatePickle state statePath
let ((), _) β runCoreM coreDst do
let (goalState, _) β goalStateUnpickle statePath (β getEnv)
let metaM : MetaM (List Expr) := do
goalState.goals.mapM Ξ» goal => goalState.withContext goal goal.getType
let types β metaM.run'
checkTrue "Goals" $ types[0]!.equal type
def test_pickling_env_extensions : TestM Unit := do
let coreSrc : Core.State := { env := β getEnv }
let coreDst : Core.State := { env := β getEnv }
IO.FS.withTempFile Ξ» _ statePath => do
let ((), _) β runCoreM coreSrc $ transformTestT runTermElabMInCore do
let .ok e β elabTerm (β `(term|(2: Nat) β€ 3 β§ (3: Nat) β€ 5)) .none | unreachable!
let state β GoalState.create e
let .success state _ β state.tacticOn' 0 (β `(tactic|apply And.intro)) | unreachable!
let goal := state.goals[0]!
let type β goal.withContext do
let .ok type β elabTerm (β `(term|(2: Nat) β€ 3)) (.some $ .sort 0) | unreachable!
instantiateMVars type
let .success state1 _ β state.tryTacticM goal (Tactic.assignWithAuxLemma type) | unreachable!
let parentExpr := state1.parentExpr!
checkTrue "src has aux lemma" $ parentExpr.getUsedConstants.any isAuxLemma
goalStatePickle state1 statePath
let ((), _) β runCoreM coreDst $ transformTestT runTermElabMInCore do
let (state1, _) β goalStateUnpickle statePath (β getEnv)
let parentExpr := state1.parentExpr!
checkTrue "dst has aux lemma" $ parentExpr.getUsedConstants.any isAuxLemma
return ()
/-- Synthetic mvars in this case creates closures. These cannot be pickled. -/
def test_pickling_synthetic_mvars : TestM Unit := do
let coreSrc : Core.State := { env := β getEnv }
IO.FS.withTempFile Ξ» _ statePath => do
let stateGenerate : MetaM GoalState := runTermElabMInMeta do
let type β Elab.Term.elabTerm (β `(term|(0 : Nat) < 1)) .none
let state β GoalState.create type
let .success state _ β state.tryHave .unfocus `h "0 < 2" | unreachable!
assert! state.savedState.term.elab.syntheticMVars.size > 0
return state
let ((), _) β runCoreM coreSrc do
let state β stateGenerate.run'
goalStatePickle state statePath
structure Test where
name : String
routine: TestM Unit
protected def Test.run (test: Test) (env: Environment) : IO LSpec.TestSeq := do
-- Create the state
let state : MultiState := {
coreContext := β createCoreContext #[],
env,
}
match β ((runTest $ test.routine).run' state).toBaseIO with
| .ok e => return e
| .error e =>
return LSpec.check s!"Emitted exception: {e.toString}" (e.toString == "")
def suite (env : Environment): List (String Γ IO LSpec.TestSeq) :=
let tests: List Test := [
{ name := "environment", routine := test_pickling_environment, },
{ name := "goal simple", routine := test_goal_state_simple, },
{ name := "goal synthetic mvars", routine := test_pickling_synthetic_mvars, },
{ name := "extensions", routine := test_pickling_env_extensions, },
]
tests.map (fun test => (test.name, test.run env))
end Pantograph.Test.Serial
|