5. The smt! Notation
smt! t builds the term t, written in a syntax close to Lean's own, as an Env action: ← smt! x + 1 < y. With open Cvc.Typed it builds typed terms, with open Cvc.Untyped sort-erased ones.
Each form is defined by the theory it belongs to, so smt! accepts a form only where that theory is imported; import Cvc imports them all.
open Cvc Typed in
#eval Env.runIO do
let x ← Term.mkSymbolAs Int "x"
let b ← Term.mkSymbolAs Bool "b"
let f ← Term.mkSymbolAs (Int → Int) "f"
let two ← Term.mkInt 2
println! "{← smt! if b ∧ x ≥ 0 then f (x + 1) else -x}"
let q ← smt!
let y ← x * 2; ∀ (z : Int), z < y → f z ≠ y
println! "{q}"
println! "{← smt! (fun (z : Int) => z % 2 = 1) x}"
println! "{← smt! <[0, x, 10]}"
println! "{← smt! ![x.intDiv two] = 1}"
5.1. Forms
form | meaning |
|---|---|
| a term in scope (a symbol, a bound variable, …), and application |
| grouping |
|
any Lean term of type |
|
|
| a lambda |
| quantifiers |
| Booleans and if-then-else |
|
an |
| a match on a datatype, see datatypes |
| records, see datatypes |
T is a Lean type in the typed layer; in the sort-erased one, it may also be a Srt.
5.2. Operators
Operators use Lean's symbols, at Lean's precedences.
operators | operations |
|---|---|
| Boolean connectives |
| equality and distinctness |
|
arithmetic, |
| comparisons |
| bit-vector and, or, xor, left shift and logical right shift |
| sets |
| disjoint bag union |
| sequence concatenation |
The binary operators → = ≠ < ≤ > ≥ + - * ⊻ ∪ ∩ ∖ ⊎ ++ ∧ ∨ also have an n-ary form in brackets: ∧[a, b, c], +[x, y, z], and <[0, x, 10], which chains: 0 < x ∧ x < 10.
An operation with no notation, such as division, is written with its term constructor and ![…], as in the last line of the example above.
Grammars and regular expressions have notations of their own, smt.grammar! and regex!.