Laurel User Guide

3.2. Expressions and Statements🔗

Laurel uses a unified StmtExpr type that contains both expression-like and statement-like constructs. This avoids duplication of shared concepts such as conditionals and variable declarations.

3.2.1. Operations🔗

🔗inductive type
Strata.Laurel.Operation : Type
Strata.Laurel.Operation : Type

Primitive operations available in Laurel expressions (each constructor is documented individually below).

Equality on composite types uses reference equality for impure types and structural equality for pure ones.

Constructors

Eq : Strata.Laurel.Operation

Equality test. Uses reference equality for impure composite types, structural equality for pure ones.

Neq : Strata.Laurel.Operation

Inequality test.

And : Strata.Laurel.Operation

Logical conjunction (eager).

Or : Strata.Laurel.Operation

Logical disjunction (eager).

Not : Strata.Laurel.Operation

Logical negation.

Implies : Strata.Laurel.Operation

Logical implication (short-circuit).

AndThen : Strata.Laurel.Operation

Short-circuit logical conjunction. Only evaluates the second argument if the first is true.

OrElse : Strata.Laurel.Operation

Short-circuit logical disjunction. Only evaluates the second argument if the first is false.

Neg : Strata.Laurel.Operation

Arithmetic negation. Works on Int and Float64.

Add : Strata.Laurel.Operation

Addition. Works on Int and Float64.

Sub : Strata.Laurel.Operation

Subtraction. Works on Int and Float64.

Mul : Strata.Laurel.Operation

Multiplication. Works on Int and Float64.

Div : Strata.Laurel.Operation

Euclidean division. Works on Int and Float64.

Mod : Strata.Laurel.Operation

Euclidean modulus. Works on Int and Float64.

DivT : Strata.Laurel.Operation

Truncation division.

ModT : Strata.Laurel.Operation

Truncation modulus.

Lt : Strata.Laurel.Operation

Less than. Works on Int and Real.

Leq : Strata.Laurel.Operation

Less than or equal. Works on Int and Real.

Gt : Strata.Laurel.Operation

Greater than. Works on Int and Real.

Geq : Strata.Laurel.Operation

Greater than or equal. Works on Int and Real.

StrConcat : Strata.Laurel.Operation

String concatenation.

3.2.2. The StmtExpr Type🔗

🔗inductive type
Strata.Laurel.StmtExpr : Type
Strata.Laurel.StmtExpr : Type

The unified statement-expression type for Laurel programs.

StmtExpr contains both statement-like constructs (conditionals, loops, assignments, returns) and expression-like constructs (literals, identifiers, operations, calls). Using a single type avoids duplication of shared concepts such as conditionals and variable declarations.

Constructors

IfThenElse
  (cond thenBranch :
    Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (elseBranch :
    Option (Strata.Laurel.AstNode Strata.Laurel.StmtExpr)) :
  Strata.Laurel.StmtExpr

Conditional with a then-branch and optional else-branch.

Block
  (statements :
    List (Strata.Laurel.AstNode Strata.Laurel.StmtExpr))
  (label : Option String) : Strata.Laurel.StmtExpr

A sequence of statements with an optional label for Exit.

While (cond : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (invariants :
    List (Strata.Laurel.AstNode Strata.Laurel.StmtExpr))
  (decreases :
    Option (Strata.Laurel.AstNode Strata.Laurel.StmtExpr))
  (body : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (postTest : Bool) : Strata.Laurel.StmtExpr

A while loop with a condition, invariants, optional termination measure, and body. Only allowed in impure contexts.

postTest selects when the condition is tested relative to the body:

  • false (default) — a pre-test loop (while): the condition is checked before the body, so the body may run zero times.

  • true — a post-test loop (do … while): the body runs once before the condition is first checked, so it always runs at least once.

Invariants are checked at the loop head (before each body) in both cases. A post-test loop is lowered to the pre-test form by the EliminateDoWhile pass.

Exit (target : String) : Strata.Laurel.StmtExpr

Exit a labelled block. Models break and continue statements.

Return
  (value :
    Option (Strata.Laurel.AstNode Strata.Laurel.StmtExpr)) :
  Strata.Laurel.StmtExpr

Return from the enclosing procedure with an optional value.

LiteralInt (value : Int) : Strata.Laurel.StmtExpr

An integer literal.

LiteralBool (value : Bool) : Strata.Laurel.StmtExpr

A boolean literal.

LiteralString (value : String) : Strata.Laurel.StmtExpr

A string literal.

LiteralDecimal (value : StrataDDM.Decimal) :
  Strata.Laurel.StmtExpr

A decimal literal.

LiteralBv (value width : Nat) : Strata.Laurel.StmtExpr

A bitvector literal with value and width.

Var (var : Strata.Laurel.Variable) : Strata.Laurel.StmtExpr

A variable reference or declaration. When var is Variable.Local, this is a reference that evaluates to the variable's value. When var is Variable.Declare, this is a declaration without an initializer (used as a standalone statement in a block).

Assign
  (targets :
    List (Strata.Laurel.AstNode Strata.Laurel.Variable))
  (value : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Assignment to one or more targets. Multiple targets are only supported with identifier targets and a call as the RHS.

IncrDecr (mode : Strata.Laurel.IncrDecrMode)
  (op : Strata.Laurel.IncrDecrOp)
  (target : Strata.Laurel.AstNode Strata.Laurel.Variable) :
  Strata.Laurel.StmtExpr

Java-style increment/decrement operator. The target must be a Local or Field Variable. As an expression, prefix form yields the new value (after the update) and postfix form yields the old value (before the update). As a statement the yielded value is discarded. Eliminated by the EliminateIncrDecrAndCompoundAssign pass before lifting imperative expressions.

CompoundAssign (op : Strata.Laurel.Operation)
  (target : Strata.Laurel.AstNode Strata.Laurel.Variable)
  (rhs : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

C-style compound assignment (x += e, x -= e, x *= e, x /= e, x %= e), plus x ^= e for string concatenation (Laurel uses ^ for concat, OCaml-style, not bitwise XOR). Lowers to target := target op rhs and yields the new value. The target must be a Local or Field Variable. Invariant: op is one of Add/Sub/Mul/Div/Mod/StrConcat — the only operators the concrete-to-abstract translator ever constructs here. Downstream sites may treat any other Operation as a StrataBug. Eliminated by the EliminateIncrDecrAndCompoundAssign pass before lifting imperative expressions.

PureFieldUpdate
  (target : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (fieldName : Strata.Laurel.Identifier)
  (newValue :
    Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Update a field on a pure (value) type, producing a new value.

StaticCall (callee : Strata.Laurel.Identifier)
  (arguments :
    List (Strata.Laurel.AstNode Strata.Laurel.StmtExpr)) :
  Strata.Laurel.StmtExpr

Call a static procedure by name with the given arguments. Primitive operators are calls too: x + y is a StaticCall to the built-in wrapper $add. See Operation.procName.

New (ref : Strata.Laurel.Identifier)
  (typeArgs :
    List (Strata.Laurel.AstNode Strata.Laurel.HighType) :=
    []) :
  Strata.Laurel.StmtExpr

Create new object (new). typeArgs carries explicit instantiation arguments for a generic composite, e.g. new Box<int>ref = Box, typeArgs = [int]. Empty for a non-generic new C (the common case and the pre-existing surface syntax), so the monomorphizer can read the concrete instantiation directly off the allocation site rather than recovering it from surrounding context.

This : Strata.Laurel.StmtExpr

Reference to the current object (this/self).

ReferenceEquals
  (lhs rhs : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Reference equality test between two expressions.

AsType
  (target : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (targetType :
    Strata.Laurel.AstNode Strata.Laurel.HighType) :
  Strata.Laurel.StmtExpr

Type cast: treat the target as the given type.

IsType
  (target : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (type : Strata.Laurel.AstNode Strata.Laurel.HighType) :
  Strata.Laurel.StmtExpr

Type test: check whether the target is an instance of the given type.

InstanceCall
  (target : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (callee : Strata.Laurel.Identifier)
  (arguments :
    List (Strata.Laurel.AstNode Strata.Laurel.StmtExpr)) :
  Strata.Laurel.StmtExpr

Call an instance method on a target object.

Quantifier (mode : Strata.Laurel.QuantifierMode)
  (param : Strata.Laurel.Parameter)
  (trigger :
    Option (Strata.Laurel.AstNode Strata.Laurel.StmtExpr))
  (body : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Quantification (universal or existential) over a typed parameter with an optional trigger.

Assigned
  (name : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Check whether a variable has been assigned.

Old (value : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Refer to the pre-state value of an expression in a postcondition.

Fresh
  (value : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Check whether a reference is freshly allocated. May only target impure composite types.

Assert
  (condition : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (summary : Option String) : Strata.Laurel.StmtExpr

Assert a condition, generating a proof obligation. The optional summary is a human-readable description of the property being checked.

Assume
  (condition :
    Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Assume a condition, restricting the state space.

Throw
  (value : Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Throw a value on the exceptional channel. The operand is unconstrained at the throw site; the thrown types are reconciled at each enclosing catch (typed at their least common ancestor) and against the procedure's declared throwsType. See the Exceptions section of the Laurel User Guide.

Try (body : Strata.Laurel.AstNode Strata.Laurel.StmtExpr)
  (catches : List Strata.Laurel.CatchClause)
  (finally? :
    Option (Strata.Laurel.AstNode Strata.Laurel.StmtExpr)) :
  Strata.Laurel.StmtExpr

Structured exception handler: a body, an ordered list of catch clauses (tried first-match-wins), and an optional finally arm that runs on every exit path. See the Exceptions section of the Laurel User Guide.

ProveBy
  (value proof :
    Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Attach a proof hint to a value. The semantics are those of value, but proof helps discharge assertions in value.

ContractOf (type : Strata.Laurel.ContractType)
  (function :
    Strata.Laurel.AstNode Strata.Laurel.StmtExpr) :
  Strata.Laurel.StmtExpr

Extract the contract (reads, modifies, precondition, or postcondition) of a function.

Abstract : Strata.Laurel.StmtExpr

Marker for abstract contracts. Makes the containing type abstract.

All : Strata.Laurel.StmtExpr

Refers to all objects in the heap. Used in reads or modifies clauses.

Hole (deterministic : Bool := true)
  (type :
    Option (Strata.Laurel.AstNode Strata.Laurel.HighType) :=
    none) :
  Strata.Laurel.StmtExpr

A hole represents an unknown expression. This can be used to represent programs that are still under development, for example the program 3 + The defining property of a hole is that interaction with it and other code should not produce any errors. Besides representing partial user programs, holes can also be used to handle under development parts of compilers that target Laurel.

  • deterministic: if true, the hole represents a deterministic unknown (translated as an uninterpreted function); if false, a nondeterministic unknown (translated as a havoced variable). Nondeterministic holes are not allowed in functions.

  • type: this property is used internally by Laurel and can be left to its default value. Internal usage: inferred by the hole type inference pass; none means not yet inferred.