Satisfiability Modulo Theories

Nikolaj Bjørner
Microsoft Research

Contents

Lectures

  1. An Introduction to Satisfiability Modulo Theories

  2. SMT Solving Algorithms

  3. Quantifier Reasoning Engines

  4. Optimization with MaxSAT

Bio

  • 90's: DTU, DIKU, Stanford
  • This is me a week before fixing my thesis topic Baby
  • Late 90's: Kestrel Institute
  • Early 2000s: XDegrees (file sharing startup)
  • 2002-06: Distributed File Replication @ Microsoft
  • 2006: MSR: Z3, Network Verification SecGuru

Four Dimensions to SMT solvers


Applications: what is it for?



Queries: what kind of formulas?



Theories: what can expressed?



Algorithms: how are answers found?

Z3

  • A state-of-art Satisfiability Modulo Theories (SMT) solver



  • On github: https://github.com/Z3prover/z3.git
    • MIT open source license
    • Developments: Scalable simplex solver, Strings, Horn clauses, floating points, SAT extensions

Some Z3 Applications

  • Program Verification
    • VCC, Everest, Dafny, Havoc, Leon

  • Symbolic Execution
    • SAGE, Pex, KLEE

  • Software Model Checking
    • Static Driver Verifier, Smash, SeaHorn

  • Configurations
    • Network Verification with SecGuru
    • Dynamics Product Configuration

Basic SAT

\[\begin{mdmathpre}%mdk (\mathid{Tie}~\vee \mathid{Shirt})~\wedge (\neg \mathid{Tie}~\vee \mathid{Shirt})~\wedge (\neg \mathid{Tie}~\vee \neg \mathid{Shirt}) \end{mdmathpre}%mdk \]



  Tie, Shirt = Bools('Tie Shirt')
  s = Solver()
  s.add(Or(Tie, Shirt), Or(Not(Tie), Shirt), Or(Not(Tie), Not(Shirt)))
  print s.check()
  print s.model()

Basic SMT

I = IntSort()
f = Function('f', I, I)
x, y, z = Ints('x y z')
A = Array('A',I,I)

fml = Implies(x + 2 == y, f(Select(Store(A, x, 3), y - 2)) == f(y - x + 1))

s = Solver()
s.add(Not(fml))
print s.check()

SAT/SMT

SATSMT

Logical Queries - SAT+



$\hspace{2cm}$ sat $\hspace{1.3cm}$ $\varphi$ $\hspace{1.3cm}$ unsat


$\hspace{1.6cm}$ model $\hspace{1.3cm}$ $\varphi$ $\hspace{1.3cm}$ (clausal) proof


$\hspace{0.6cm}$ correction set $\hspace{0.3cm}$ $\subseteq \varphi_1, \ldots, \varphi_n \supseteq $ $\hspace{0.2cm}$ core


local min correction set $\hspace{0.05cm}$ $ \subseteq \varphi_1, \ldots, \varphi_n \supseteq$ $\hspace{0.2cm}$ local min core


min correction set $\hspace{0.35cm}$ $ \subseteq \varphi_1, \ldots, \varphi_n \supseteq$ $\hspace{0.2cm}$ min core


$\hspace{3.2cm}$ $\max x \varphi(x)$

Logical Queries

\[\begin{mdmathpre}%mdk \mathrm{Satisfiability}~~~&~\varphi \rightsquigarrow \mathid{sat},~\mathid{unsat},~\mathid{timeout}~\smallskip \\ \mathrm{Certificates}~~~~~&~\varphi \rightsquigarrow \mathid{model},~\mathid{proof},~\mathid{unsat}~\mathid{core}~\smallskip\\ \mathrm{Interpolation}~~~~&~\varphi[\mathid{x},\mathid{y}]~\rightarrow \mathid{I}[\mathid{x}]~\rightarrow \psi[\mathid{x},\mathid{z}]~\smallskip\\ \mathrm{Optimization}~~~~~&~\max \mathid{x}~\mid \varphi \smallskip \\ \mathrm{Consequences}~~~~~&~\varphi \rightarrow \varphi_1~\wedge \ldots \wedge \varphi_\mathid{n}\smallskip\\ \mathrm{Sat\ subsets}~~~~~&~\psi_1~\wedge \psi_2,\ \psi_1~\wedge \psi_3\smallskip\\ \mathrm{Unsat\ cores}~~~~~&~\neg(\psi_1~\wedge \psi_2),\ \neg(\psi_1~\wedge \psi_3)\medskip\\ \mathrm{Model\ counting}~~&~|\{~\mathid{x}~\mid \varphi\}|~\medskip\\ \mathrm{All\ models}~~~~~~&~\mathid{Ideal}(\varphi),~\mathid{M}_1~\models \varphi,~\mathid{M}_2~\models \varphi,~\ldots \medskip\\ \mathrm{Model\ probability}~&~\ldots \end{mdmathpre}%mdk \]

Theories

Equality and Uninterpreted functions

EUF

  (declare-sort A)
  (declare-fun f (A) A)
  (declare-const x A)
  (assert (= (f (f x)) x))
  (assert (= (f (f (f x))) x))
  (check-sat)
  
  (assert (not (= (f x) x)))
  (check-sat)

Deciding Equality

\begin{tikzpicture} \matrix[nodes={draw},row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {:}; & \node [circle, draw] (a) {$a$}; & \node [circle, draw] (b) {$b$}; & \node [circle, draw] (c) {$c$}; & \node [circle, draw] (d) {$d$}; & \node [circle, draw] (e) {$e$}; & \node [circle, draw] (s) {$s$}; & \node [circle, draw] (t) {$t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b: $}; & \node [circle, draw] (ab) {$a, b$}; & \node [circle, draw] (c) {$c$}; & \node [circle, draw] (d) {$d$}; & \node [circle, draw] (e) {$e$}; & \node [circle, draw] (s) {$s$}; & \node [circle, draw] (t) {$ t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c: $}; & \node [circle, draw] (abc) {$a, b, c$}; & \node [circle, draw] (d) {$d$}; & \node [circle, draw] (e) {$e$}; & \node [circle, draw] (s) {$s$}; & \node [circle, draw] (t) {$t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e: $}; & \node [circle, draw] (abc) {$a, b, c$}; & \node [circle, draw] (de) {$d, e$}; & \node [circle, draw] (s) {$s$}; & \node [circle, draw] (t) {$t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e, b = s: $}; & \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (de) {$d, e$}; & \node [circle, draw] (t) {$t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e, b = s, d = t: $}; & \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; \\ }; \end{tikzpicture}

Disequalities

\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e, b = s, d = t, a \neq d: $}; & \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e, b = s, d = t, c \neq s: $}; & \node [circle, draw, color=red] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; \\ }; \end{tikzpicture}
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [rectangle, draw=none] (eq) {$a = b, b = c, d = e, b = s, d = t, e \neq t: $}; & \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw, color=red] (det) {$d, e, t$}; \\ }; \end{tikzpicture}

Variants of union-find are effective to decide equality.

Free functions

$a = b, b = c, d = e, b = s, d = t, f(a, g(d)) \neq f(b, g(e))$

Congruence rule

\[ x_1 = y_1 \cdots x_n = y_n \ \Rightarrow \ f(x_1, \ldots, x_n) = f(y_1, \ldots, y_n) \]

Naming sub-terms

$a = b, b = c, d = e, b = s, d = t, f(a, g(d)) \neq f(b, {\color{red}v_1})$ ${\color{red}v_1 := g(e)}$


$a = b, b = c, d = e, b = s, d = t, f(a, {\color{red}v_2}) \neq f(b, v_1)$ $v_1 := g(e), {\color{red}v_2 := g(d)}$


$a = b, b = c, d = e, b = s, d = t, {\color{red}v_3} \neq f(b, v_1)$ $v_1 := g(e), v_2 := g(d), {\color{red}v_3 := f(a, v_2)}$


$a = b, b = c, d = e, b = s, d = t, v_3 \neq {\color{red}v_4}$ $v_1 := g(e), v_2 := g(d), v_3 := f(a, v_2), {\color{red}v_4 := f(b, v_1)}$

\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw] (v1) {$v_1$}; & \node [circle, draw] (v2) {$v_2$}; & \node [circle, draw] (v3) {$v_3$}; & \node [circle, draw] (v4) {$v_4$}; \\ }; \end{tikzpicture}

Applying Congruence (1)

\[\begin{array}{l} a = b, b = c, d = e, b = s, d = t, v_3 \neq v_4 \\ v_1 := g(e), v_2 := g(d), v_3 := f(a, v_2), v_4 := f(b, v_1) \end{array} \]
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw] (v1) {$v_1$}; & \node [circle, draw] (v2) {$v_2$}; & \node [circle, draw] (v3) {$v_3$}; & \node [circle, draw] (v4) {$v_4$}; \\ }; \end{tikzpicture}
\[ e = d \ \Rightarrow \ g(e) = g(d) \]
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw, color=red] (v12) {$v_1, v_2$}; & \node [circle, draw] (v3) {$v_3$}; & \node [circle, draw] (v4) {$v_4$}; \\ }; \end{tikzpicture}

Applying Congruence (2)

\[\begin{array}{l} a = b, b = c, d = e, b = s, d = t, v_3 \neq v_4 \\ v_1 := g(e), v_2 := g(d), v_3 := f(a, v_2), v_4 := f(b, v_1) \end{array} \]

$a = b, b = c, d = e, b = s, d = t, f(a, g(d)) \neq f(b, g(e))$

\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw] (v12) {$v_1, v_2$}; & \node [circle, draw] (v3) {$v_3$}; & \node [circle, draw] (v4) {$v_4$}; \\ }; \end{tikzpicture}
\[ a = b, v_2 = v_1 \Rightarrow \ f(a, v_2) = f(b, v_1) \]
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw] (v12) {$v_1, v_2$}; & \node [circle, draw, color=red] (v34) {$v_3, v_4$}; \\ }; \end{tikzpicture}

EUF Models

A satisfiable version:

$a = b, b = c, d = e, b = s, d = t, f(a, g(d)) \neq {\color{red}f(g(e), b)}$

$a = b, b = c, d = e, b = s, d = t, v_3 \neq v_4$
$v_1 := g(e), v_2 := g(d), v_3 := f(a, v_2), v_4 := f(v_1, b)$

\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$a, b, c, s$}; & \node [circle, draw] (det) {$d, e, t$}; & \node [circle, draw] (v12) {$v_1, v_2$}; & \node [circle, draw] (v3) {$v_3$}; & \node [circle, draw] (v4) {$v_4$}; \\ }; \end{tikzpicture}

EUF Models (II)

  • Associate a distinct value with each equivalence class.
\begin{tikzpicture} \matrix[nodes={draw}, row sep=0.3cm,column sep=0.5cm] { \node [circle, draw] (abcs) {$\diamond_1: a, b, c, s$}; & \node [circle, draw] (det) {$\diamond_2: d, e, t$}; & \node [circle, draw] (v12) {$\diamond_3: v_1, v_2$}; & \node [circle, draw] (v3) {$\diamond_4: v_3$}; & \node [circle, draw] (v4) {$\diamond_5: v_4$}; \\ }; \end{tikzpicture}
  • $M(a) = M(b) = M(c) = M(s) := \diamond_1$
  • $M(d) = M(e) = M(t) := \diamond_2$
  • $M(g) = \{ \diamond_1 \mapsto \diamond_3, \diamond_2 \mapsto \diamond_3, \mathrm{else} \mapsto \diamond_6 \}$
  • $M(f) = \{ (\diamond_1, \diamond_3) \mapsto \diamond_4, (\diamond_3, \diamond_2) \mapsto \diamond_5, \mathrm{else} \mapsto \diamond_7 \}$

Linear Arithmetic

(set-logic QF_IDL) ; optional in Z3
(declare-fun t11 () Int)
(declare-fun t12 () Int)
(declare-fun t21 () Int)
(declare-fun t22 () Int)
(declare-fun t31 () Int)
(declare-fun t32 () Int)

(assert (and (>= t11 0) (>= t12 (+ t11 2)) (<= (+ t12 1) 8)))
(assert (and (>= t21 0) (>= t22 (+ t21 3)) (<= (+ t22 1) 8)))
(assert (and (>= t31 0) (>= t32 (+ t31 2)) (<= (+ t32 3) 8)))
(assert (or (>= t11 (+ t21 3)) (>= t21 (+ t11 2))))
(assert (or (>= t11 (+ t31 2)) (>= t31 (+ t11 2))))
(assert (or (>= t21 (+ t31 2)) (>= t31 (+ t21 3))))
(assert (or (>= t12 (+ t22 1)) (>= t22 (+ t12 1))))
(assert (or (>= t12 (+ t32 3)) (>= t32 (+ t12 1))))
(assert (or (>= t22 (+ t32 3)) (>= t32 (+ t22 1))))
(check-sat)
(get-model) ; display the model  

Linear Arithmetic Example

Algorithmic Fragments of Arithmetic

Logic Fragment Solver Example
LRA Linear Real Arithmetic Dual Simplex $x + \frac{1}{2}y \leq 3$
LIA Linear Integer Arithmetic CutSat $a + 3b \leq 3$
LIRA Mixed Real/Integer Cuts + Branch $x + a \geq 4$
IDL Integer Difference Logic Floyd-Warshall $a - b \leq 4$
RDL Real Difference Logic Bellman-Ford
UTVPI Unit two-variable per inequality $x + y \leq 4$
NRA Polynomial Real Arithmetic Model based CAD $x^2 + y^2 < 1$

Other Fragments of Arithmetic

  • NIA - There is no decision procedure for integer polynomial constraints

    • Z3 falls back to incomplete heuristics
    • NIA over bounded integers may get translated to bit-vector constraints


    Other theories that admit custom solvers:

  • Bi-linear real arithmetic $\vec{x}A\vec{y} \leq \vec{b}$

  • Non-unit two-variable per inequality $ax + by \leq c$

  • At most one unit positive variable per inequality (Horn)

Bellman-Ford - a selection

(set-logic QF_IDL) ; optional in Z3
(declare-fun t11 () Int)
(declare-fun t12 () Int)
(declare-fun t21 () Int)
(declare-fun t22 () Int)
(declare-fun t31 () Int)
(declare-fun t32 () Int)

(assert (and (>= t11 0) ...))
(assert (and (>= t21 0) ...))
(assert (and (>= t31 0) (>= t32 (+ t31 2)) (<= (+ t32 3) 8)))
(assert (or ... (>= t21 (+ t11 2))))
(assert (or (>= t21 (+ t31 2)) ...))
(check-sat)
(get-model) ; display the model  

Bellman-Ford

Solve difference logic using graph $O(m\cdot n)$ Bellman-Ford network flow algorithm. Negative cycle $\Rightarrow$ unsat.

BellmanFord

General form Simplex [20]

General form $Ax = 0$ and $lo_j \leq x_j \leq hi_j$

\[ x \geq 0, (x + y \leq 2 \vee x + 2y \geq 6), (x + y \geq 2 \vee x + 2y > 4) \]

$\leadsto$

\[\begin{mdmathpre}%mdk \mdmathindent{2}\mathid{s}_1~:=~\mathid{x}~+~\mathid{y},~\mathid{s}_2~:=~\mathid{x}~+~2\mathid{y},\\ \mdmathindent{2}\mathid{x}~\geq 0,~(\mathid{s}_1~\leq 2~\vee \mathid{s}_2~\geq 6),~(\mathid{s}_1~\geq 2~\vee \mathid{s}_2~>~4) \end{mdmathpre}%mdk \]

Only bounds (e.g., $s_1 \leq 2$) are asserted during search.

From Definitions to a Tableau

${\color{red}s_1} := x + y, {\color{red}s_2} := x + 2y$



${\color{red}s_1} = x + y$
${\color{red}s_2} = x + 2y$



${\color{red}s_1} - x - y = 0$ - ${\color{red}s_1, s_2}$ are basic (dependent)
${\color{red}s_2} - x - 2y = 0$ - $x, y$ are non-basic

Pivoting

  • Value of non-basic variable $x_j$ can be chosen between $lo_j$ and $hi_j$.
  • Value of basic variable is a function of non-basic variable values.
  • Pivoting swaps basic and non-basic variables.
    • used to get values of basic variables within bounds.

Pivoting example

${\color{red}s_1} - x - y = 0$ - ${\color{red}s_1, s_2}$ are basic (dependent)
${\color{red}s_2} - x - 2y = 0$ - $x, y$ are non-basic $x \geq 0, (s_1 \leq 2 \vee s_2 \geq 6), (s_1 \geq 2 \vee s_2 > 4)$


Initial values: $x = y = s_1 = s_2 = 0$


Bounds $x \geq 0, s_1 \leq 2, s_1 \geq 2$:


$s_1 := 2$, make $s_1$ non-basic.
${\color{red}y} + x - s_1 = 0$ - ${\color{red}y, s_2}$ are basic (dependent)
${\color{red}s_2} + x - 2s_1 = 0$ - $s_1, y$ are non-basic

Arrays

(define-sort A () (Array Int Int))
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun a1 () A)

(push)
(assert (= (select a1 x) x))
(assert (= (store a1 x y) a1))
(check-sat)
(get-model)
(assert (not (= x y)))
(check-sat)
(pop)

(define-fun all1_array () A ((as const A) 1))
(simplify (select all1_array x))

(define-sort IntSet () (Array Int Bool))
(declare-fun a () IntSet)
(declare-fun b () IntSet)
(declare-fun c () IntSet)
(push) ; illustrate map
(assert (not (= ((_ map and) a b) ((_ map not) ((_ map or) ((_ map not) b) ((_ map not) a))))))
(check-sat)
(pop)    

Arrays

Arrays as Combinators [39]

  A = Array(Index, Elem) # array sort 
  
  a[i]             # index array 'a' at index 'i'
                   # Select(a, i)
  
  Store(a, i, v)   # update array 'a' with value 'v' at index 'i'
                   # = lambda j: If(i == j, v, a[j])
    
  Const(v, A)      # constant array
                   # = lambda j: v
  
  Map(f, a)        # map function 'f' on values of 'a'
                   # = lambda j: f(a[j])

  Ext(a, b)        # Extensionality
                   # Implies(a[Ext(a, b)] == b[Ext(a, b)], a == b)

Array Decision Procedure

Example Store(a, i, v)

  • Each occurrence of Store(a, i, v) and b[j],
    • Assert Store(a, i, v)[j] == If(i == j, v, a[j])
    • Assert Store(a, i, v)[i] == v

  • Each shared occurrences of $a, b$:
    • Assert $a[\mbox{Ext}(a, b)] = b[\mbox{Ext}(a,b)] \ \implies \ a = b$.

Array Decision Procedure (2)

Example Store(a, i, v)

  • Each occurrence of Store(a, i, v) and b[j],
    • Assert Store(a, i, v)[j] == If(i == j, v, a[j])
    • Assert Store(a, i, v)[i] == v

  • Each shared occurrences of $a, b$:
    • Assert $a[\mbox{Ext}(a, b)] = b[\mbox{Ext}(a,b)] \ \implies \ a = b$.

  • Suppose we are given a model $M$ satisfying all asserted equalities.
    • $M$ assigns values to $a[i]\in \mathcal{T}$ terms.
    • Extend: $M(a) := \left[ M(i) \mapsto M(a[i])\; \mid\; a[i] \in \mathcal{T}; \ \mbox{else}\ \mapsto \diamond_{\mbox{default}} \right]$
    • Claim: $M(a)$ satisfies Store axioms.

Efficient Array Decision Procedures

  • Use current partial interpretation to guide axiom instantiation.

  • Rough sketch:

    • If $u := Sore(a, i, v), w := b[j], u \sim b$ (congruent) in current state
      • Assert $i = j \vee u[j] = a[j]$.
    • If $u := Store(a, i, v), w := b[j], a \sim b$ in current state
      • Assert $i = j \vee Store(a, i, v)[j] = a[j]$
  • Also important to limit set of $i, j$ pairs.

    • Z3 uses relevancy propagation to prune don't care literals
    • Boolector uses dual propagation to extract small implicant

Bit-Vectors

(define-fun is-power-of-two ((x (_ BitVec 4))) Bool 
  (= #x0 (bvand x (bvsub x #x1))))
(declare-const a (_ BitVec 4))
(assert 
 (not (= (is-power-of-two a) 
         (or (= a #x0) 
             (= a #x1) 
             (= a #x2) 
             (= a #x4) 
             (= a #x8)))))
(check-sat)

Bit-Vectors

Floating point example

(declare-fun X () (_ FloatingPoint 11 53))

(assert (fp.isNormal X))
(assert (not (fp.isSubnormal X)))
(assert (not (fp.isZero X)))
(assert (not (fp.isInfinite X)))
(assert (not (fp.isNaN X)))
(assert (not (fp.isNegative X)))
(assert (fp.isPositive X))

(check-sat)
(get-model)

Floating Points demo

Sequence Example

(declare-const a String)
(declare-const b String)
(declare-const c String)
(assert (str.prefixof b a))
(assert (str.suffixof c a))
(assert (= (str.len a) (+ (str.len b) (str.len c))))
(assert (not (= a (str.++ b c))))
(check-sat)  

Sequences and Strings

Queues

\[\begin{mdmathpre}%mdk \mdmathindent{2}\mathid{xA}~=~\mathid{Bx}~\leftarrow \Gamma \\ \mdmathindent{6}\Rightarrow \mathid{A}~=~\mathid{B}_2\mathid{B}_1,~\mathid{ext}(\mathid{x},\mathid{B})~\leftarrow \Gamma,~\mathid{B}~=~\mathid{B}_1\mathid{B}_2\\ \\ \mdmathindent{2}\mathid{xA}~=~\mathid{By}~\leftarrow \Gamma\\ \mdmathindent{6}\Rightarrow \mathid{x}~=~\mathid{B}_1,~\mathid{A}~=~\mathid{B}_2\mathid{y}~\leftarrow \Gamma,~\mathid{B}~=~\mathid{B}_1\mathid{B}_2\\ \mdmathindent{6}\Rightarrow \mathid{y}~=~\mathid{A}_2,~\mathid{B}~=~\mathid{xA}_1~\leftarrow \Gamma,~\mathid{A}~=~\mathid{A}_1\mathid{A}_2\\ \mdmathindent{6}\Rightarrow \mathid{x}~=~\mathid{Bz},~\mathid{zA}~=~\mathid{y}~\leftarrow \Gamma,~\mathid{z}~\mathid{is}~\mathid{fresh}\\ \\ \mdmathindent{2}\mathid{ext}(\mathid{x},\mathid{A}),~\mathid{ext}(\mathid{x},\mathid{B})~\leftarrow \Gamma\\ \mdmathindent{6}\Rightarrow \mathid{compat}(\mathid{A},~\mathid{B},~|\mathid{x}|),~\mathid{ext}(\mathid{x},~\mathid{A})~\leftarrow \Gamma\\ \mdmathindent{5} \end{mdmathpre}%mdk \]

Algebraic Data-types

   (declare-datatypes () ((Tree Empty (Node (left Tree) (data Int) (right Tree)))))

   (declare-const t Tree)
   (assert (not (= t Empty)))
   (check-sat)
   (get-model)
sat
(model 
  (define-fun t () Tree
    (Node Empty 0 Empty))
)

Algebraic Data-types demo

Non-linear Arithmetic [29]