This PR sets up the new integrated test/bench suite. It then migrates all benchmarks and some related tests to the new suite. There's also some documentation and some linting. For now, a lot of the old tests are left alone so this PR doesn't become even larger than it already is. Eventually, all tests should be migrated to the new suite though so there isn't a confusing mix of two systems.
135 lines
5.1 KiB
Text
135 lines
5.1 KiB
Text
import Lean
|
|
open Lean Parser
|
|
|
|
/-!
|
|
This test accounts for a specialisation cache bug that was discovered in the Zulip thread
|
|
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Miscompilation.20.28incorrect.20code.29.20in.20new.20compiler/near/540037917
|
|
if the bug is around the eval at the end of the file evaluates to true instead of false.
|
|
-/
|
|
|
|
namespace Veil
|
|
|
|
inductive Mutability where
|
|
| mutable
|
|
| immutable
|
|
| inherit
|
|
deriving Inhabited, BEq, Hashable, Repr
|
|
|
|
inductive StateComponentType where
|
|
| simple (t : TSyntax ``Command.structSimpleBinder)
|
|
| complex (binders : TSyntaxArray ``Term.bracketedBinder) (dom : Term)
|
|
deriving Inhabited, BEq
|
|
|
|
structure StateComponent where
|
|
mutability : Mutability
|
|
name : Name
|
|
type : StateComponentType
|
|
deriving Inhabited, BEq
|
|
|
|
structure Module where
|
|
name : Name
|
|
signature : Array StateComponent
|
|
deriving Inhabited
|
|
|
|
end Veil
|
|
|
|
section Util
|
|
set_option autoImplicit true
|
|
def getSimpleBinderType [Monad m] [MonadError m] (sig : TSyntax `Lean.Parser.Command.structSimpleBinder) : m (TSyntax `term) := do
|
|
match sig with
|
|
| `(Lean.Parser.Command.structSimpleBinder| $_:ident : $tp:term) => pure tp
|
|
| _ => throwError s!"getSimpleBinderType: don't know how to handle {sig}"
|
|
|
|
def mkArrowStx [Monad m] [MonadQuotation m] [MonadError m] (tps : List Term) (terminator : Option $ TSyntax `term := none) : m (TSyntax `term) := do
|
|
match tps with
|
|
| [] => if let some t := terminator then return t else throwError "empty list of types and no terminator"
|
|
| [a] => match terminator with
|
|
| none => `(term| $a)
|
|
| some t => `(term| $a -> $t)
|
|
| a :: as =>
|
|
let cont ← mkArrowStx as terminator
|
|
`(term| $a -> $cont)
|
|
|
|
def complexBinderToSimpleBinder [Monad m] [MonadQuotation m] [MonadError m] (nm : TSyntax `ident) (br : TSyntaxArray `Lean.Parser.Term.bracketedBinder) (domT : TSyntax `term) : m (TSyntax `Lean.Parser.Command.structSimpleBinder) := do
|
|
let types ← br.mapM fun m => match m with
|
|
| `(bracketedBinder| ($_arg:ident : $tp:term)) => return tp
|
|
| _ => throwError "Invalid binder syntax {br}"
|
|
let typeStx ← mkArrowStx types.toList domT
|
|
let simple ← `(Lean.Parser.Command.structSimpleBinder| $nm:ident : $typeStx)
|
|
return simple
|
|
end Util
|
|
|
|
open Lean Parser Elab Command Term
|
|
|
|
namespace Veil
|
|
|
|
instance : ToString Mutability where
|
|
toString
|
|
| Mutability.mutable => "mutable"
|
|
| Mutability.immutable => "immutable"
|
|
| Mutability.inherit => "inherit"
|
|
|
|
instance : ToString StateComponentType where
|
|
toString
|
|
| StateComponentType.simple t => toString t
|
|
| StateComponentType.complex b d => s!"{b} : {d}"
|
|
|
|
instance : ToString StateComponent where
|
|
toString sc := s!"{sc.mutability} {sc.name} {sc.type}"
|
|
|
|
def StateComponentType.stx [Monad m] [MonadQuotation m] [MonadError m] (sct : StateComponentType) : m (TSyntax `term) := do
|
|
match sct with
|
|
| .simple t => getSimpleBinderType t
|
|
| .complex b d => getSimpleBinderType $ ← complexBinderToSimpleBinder (mkIdent Name.anonymous) b d
|
|
|
|
/-- Returns, e.g., `initial_msg : address → address → round → value → Prop` -/
|
|
def StateComponent.getSimpleBinder [Monad m] [MonadQuotation m] [MonadError m] (sc : StateComponent) : m (TSyntax ``Command.structSimpleBinder) := do
|
|
match sc.type with
|
|
| .simple t => return t
|
|
| .complex b d => return ← complexBinderToSimpleBinder (mkIdent sc.name) b d
|
|
|
|
def StateComponent.stx {m} [Monad m] [MonadQuotation m] [MonadError m] (sc : StateComponent) : m Syntax := sc.getSimpleBinder
|
|
def StateComponent.typeStx [Monad m] [MonadQuotation m] [MonadError m] (sc : StateComponent) : m Term := sc.type.stx
|
|
|
|
def Module.getTheoryBinders [Monad m] [MonadQuotation m] [MonadError m] (mod : Module) : m (Array (TSyntax `Lean.Parser.Term.bracketedBinder)) := do
|
|
mod.signature.filterMapM fun sc => do
|
|
match sc.mutability with
|
|
| .immutable => return .some $ ← `(bracketedBinder| ($(mkIdent sc.name) : $(← sc.typeStx)))
|
|
| _ => pure .none
|
|
|
|
def Module.getStateBinders [Monad m] [MonadQuotation m] [MonadError m] (mod : Module) : m (Array (TSyntax `Lean.Parser.Term.bracketedBinder)) := do
|
|
let res ← mod.signature.filterMapM fun sc => do
|
|
match sc.mutability with
|
|
| .mutable =>
|
|
return .some $ ← `(bracketedBinder| ($(mkIdent sc.name) : $(← sc.typeStx)))
|
|
| _ =>
|
|
-- NOTE 1: uncommenting this line makes `trigger` work correctly
|
|
pure .none
|
|
return res
|
|
|
|
-- NOTE 2: commenting out this function (or the `trace` statement) makes `trigger` work correctly
|
|
def interference (mod : Module) : CommandElabM Unit := do
|
|
trace[veil.debug] "theory binders: {← mod.getTheoryBinders}"
|
|
return
|
|
|
|
end Veil
|
|
|
|
namespace Veil
|
|
|
|
open Lean Parser Elab Command
|
|
def trigger : CommandElabM Bool := do
|
|
let sig : Array StateComponent := #[
|
|
{ mutability := .mutable, name := `leader, «type» := .simple $ ← `(Command.structSimpleBinder| x : Nat → Bool)},
|
|
{ mutability := .mutable, name := `pending, «type» := .simple $ ← `(Command.structSimpleBinder| pending : Nat → Nat → Bool)}
|
|
]
|
|
let emptyMod : Module := default
|
|
let mod := { emptyMod with signature := sig}
|
|
let binders ← mod.getStateBinders
|
|
return binders.isEmpty
|
|
|
|
/-- info: false -/
|
|
#guard_msgs in
|
|
#eval trigger
|
|
|
|
end Veil
|
|
|