\(%\usepackage{color}\)
\(%\usepackage{tcolorbox}\)
\(%\tcbuselibrary{skins}\)
\(\usepackage{pifont}\)
\(\)
\(\definecolor{fakeaaltobluel}{RGB}{00,141,229} % 0065BD\)
\(\definecolor{aaltoblue}{RGB}{00,101,189} % 0065BD\)
\(\definecolor{aaltored}{RGB}{237,41,57} % ED2939\)
\(\)
\(\definecolor{MyBoxBackground}{rgb}{0.98,0.98,1.0}\)
\(\definecolor{MyBoxBorder}{rgb}{0.90,0.90,1.0}\)
\(\definecolor{backgroundred}{rgb}{1.0,0.98,0.98}\)
\(\definecolor{shadowred}{rgb}{1.0,0.90,0.90}\)
\(\)
\(%\newcommand{\subheading}[1]{\textbf{\large\color{fakeaaltobluel}#1}}\)
\(\newcommand{\subheading}[1]{\large{\usebeamercolor[fg]{frametitle} #1}}\)
\(\)
\(\)
\(%\newtcbox{\mybox}[1][red]{on line,arc=0pt,outer arc=0pt,colback=#1!10!white,colframe=#1!50!black,boxsep=0pt,left=1pt,right=1pt,top=2pt,bottom=2pt,boxrule=0pt,bottomrule=1pt,toprule=1pt}\)
\(%\newtcbox{\mybox}[1][MyBoxBackground]{on line,arc=0pt,outer arc=0pt,colback=#1!10!white,colframe=#1!50!black,boxsep=0pt,left=1pt,right=1pt,top=2pt,bottom=2pt,boxrule=0pt,bottomrule=1pt,toprule=1pt}\)
\(\)
\(\newtcolorbox{MyBoxTitled}[1]{colback=MyBoxBackground!100!black,colframe=MyBoxBorder!100!black,boxsep=2pt,left=0pt,right=0pt,top=2pt,bottom=0pt,%enhanced,%\)
\( coltitle=red!25!black,title=#1,boxrule=1pt}\)
\(\)
\(\newtcolorbox{MyBox}[1][]{colback=MyBoxBackground!100!black,colframe=MyBoxBorder!100!black,boxsep=0pt,left=2pt,right=0pt,top=0pt,bottom=0pt,%enhanced,%\)
\( coltitle=red!25!black,boxrule=1pt,#1}\)
\(\)
\(\newenvironment{EqnBox}[1]{\begin{adjustbox}{valign=t}\begin{minipage}{#1}\begin{MyBox}[colback=backgroundred!100!black,colframe=shadowred!100!black]}{\end{MyBox}\end{minipage}\end{adjustbox}}\)
\(\)
\(\newenvironment{topbox}[1]{\begin{adjustbox}{valign=t}\begin{minipage}{#1}}{\end{minipage}\end{adjustbox}}\)
\(\)
\(\newcommand{\Blue}[1]{{\color{aaltoblue}#1}}\)
\(\newcommand{\Red}[1]{{\color{aaltored}#1}}\)
\(%\newcommand{\Emph}[1]{\emph{\color{aaltoblue}#1}}\)
\(\newcommand{\Emph}[1]{\emph{\usebeamercolor[fg]{structure} #1}}\)
\(\newcommand{\TextDef}[1]{{\bf\usebeamercolor[fg]{structure} #1}}\)
\(\)
\(\newcommand{\todo}[1]{\textbf{\Red{\Pointer #1}}}\)
\(\newcommand{\TODO}[1]{\todo{#1}}\)
\(\)
\(\newcommand{\Pointer}{\raisebox{-1ex}{\huge\ding{43}}\ }\)
\(\)
\(\)
\(%\)
\(% Common math definitions\)
\(%\)
\(\newcommand{\Set}[1]{\{#1\}}\)
\(\newcommand{\Setdef}[2]{\{{#1}\mid{#2}\}}\)
\(\newcommand{\PSet}[1]{\mathcal{P}(#1)}\)
\(\newcommand{\Pair}[2]{(#1,#2)}\)
\(\newcommand{\Card}[1]{{\vert{#1}\vert}}\)
\(\newcommand{\Tuple}[1]{(#1)}\)
\(\newcommand{\Seq}[1]{[#1]}\)
\(\newcommand{\bbZ}{\mathbb{Z}}\)
\(\newcommand{\Ints}{\mathbb{Z}}\)
\(\newcommand{\Reals}{\mathbb{R}}\)
\(\newcommand{\bbQ}{\mathbb{Q}}\)
\(\newcommand{\Rats}{\bbQ}\)
\(\newcommand{\bbN}{\mathbb{N}}\)
\(\newcommand{\Nats}{\bbN}\)
\(\)
\(\newcommand{\Floor}[1]{\lfloor #1 \rfloor}\)
\(\newcommand{\Ceil}[1]{\lceil #1 \rceil}\)
\(\)
\(\newcommand{\False}{\textsf{F}}\)
\(\newcommand{\True}{\textsf{T}}\)
\(\)
\(\newcommand{\Implies}{\rightarrow}\)
\(\newcommand{\Iff}{\leftrightarrow}\)
\(%\newcommand{\Implies}{\Rightarrow}\)
\(%\newcommand{\Iff}{\Leftrightarrow}\)
\(\newcommand{\Xor}{\oplus}\)
\(\)
\(\newcommand{\Equiv}{\equiv}\)
\(\)
\(\newcommand{\Oh}[1]{O(#1)}\)
\(%\newcommand{\Theta}[1]{\Theta(#1)}\)
\(\)
\(\newcommand{\PHP}[2]{\mathrm{php}_{#1,#2}}\)
\(\newcommand{\PH}[2]{\mathit{x}_{#1,#2}}\)
\(\)
\(\newcommand{\NP}{\textbf{NP}}\)
\(\newcommand{\coNP}{\textbf{co-NP}}\)
\(\)
\(\newcommand{\bnfdef}{\mathrel{\textup{::=}}}\)
\(\newcommand{\bnfor}{\mathrel{\mid}}\)
\(\)
\(\newcommand{\Def}{\mathrel{:=}}\)
\(\)
\(\newcommand{\LSF}{\alpha}\)
\(\newcommand{\RSF}{\beta}\)
\(\newcommand{\SF}{\phi}\)
\(\newcommand{\MF}{\gamma}\)
\(%\newcommand{\Abbrv}{\equiv}\)
\(\newcommand{\Abbrv}{\Def}\)
\(\newcommand{\AbbrvEq}{\equiv}\)
\(\newcommand{\Exists}[2]{\exists{#1}.\,#2}\)
\(%\newcommand{\E}[3]{\exists{#1{:}#2}.\,#3}\)
\(\newcommand{\E}[3]{\exists{#1{:}\,#3}}\)
\(\newcommand{\Forall}[2]{\forall{#1}.\,#2}\)
\(%\newcommand{\Furall}[3]{\forall{#1{:}#2}.\,#3}\)
\(%\newcommand{\A}[3]{\forall{#1{:}#2}.\,#3}\)
\(\newcommand{\A}[3]{\forall{#1{:}\,#3}}\)
\(\newcommand{\Models}{\models}\)
\(\newcommand{\NotModels}{\not\models}\)
\(\)
\(\newcommand{\Substf}[3]{#1[#2 \mapsto #3]}\)
\(\newcommand{\Functions}[2]{[#1 \to #2]}\)
\(\)
\(\)
\(\newcommand{\Eq}{\approx}\)
\(\newcommand{\EqS}[1]{\approx_{#1}}\)
\(\newcommand{\Neq}{\not\approx}\)
\(\)
\(%\newcommand{\Th}{\mathcal{T}}\)
\(\newcommand{\Th}{T}\)
\(\newcommand{\ThI}[1]{\Th_{#1}}\)
\(\)
\(\newcommand{\Sig}{\Sigma}\)
\(\newcommand{\SigI}[1]{\Sigma_{#1}}\)
\(\newcommand{\Interp}{I}\)
\(%\newcommand{\Interp}{{\mathcal{I}}}\)
\(\newcommand{\InterpOf}[1]{#1^\Interp}\)
\(\newcommand{\InterpIOf}[2]{#2^{#1}}\)
\(\newcommand{\InterpRestr}[1]{\Interp^{#1}}\)
\(\newcommand{\InterpI}[1]{I_{#1}}\)
\(%\newcommand{\InterpI}[1]{{\mathcal{I}_{#1}}}\)
\(%\newcommand{\InterpIOf}[2]{#2^{\InterpI{#1}}}\)
\(\newcommand{\InterpDom}{D_{\Interp}}\)
\(\newcommand{\InterpSubst}[2]{\Interp[{#1}\mapsto{#2}]}\)
\(\newcommand{\ThModels}{\mathrel{\models_{\Th}}}\)
\(\newcommand{\ThIModels}[1]{\mathrel{\models_{\ThI{#1}}}}\)
\(\)
\(% Example interpretations\)
\(\newcommand{\IInts}{\InterpI{\textrm{ints}}}\)
\(\newcommand{\IIntsOf}[1]{\InterpIOf{\IInts}{#1}}\)
\(\newcommand{\IMods}{\InterpI{\textrm{mod7}}}\)
\(\newcommand{\IModsOf}[1]{\InterpIOf{\IMods}{#1}}\)
\(\newcommand{\ISilly}{\InterpI{\textrm{silly}}}\)
\(\newcommand{\ISillyOf}[1]{\InterpIOf{\ISilly}{#1}}\)
\(\)
\(\)
\(%\newcommand{\El}[1]{\textup{e}_{#1}}\)
\(\)
\(\newcommand{\ElemI}{\textup{\ding{40}}}\)
\(\newcommand{\ElemII}{\textup{\ding{41}}}\)
\(\newcommand{\ElemIII}{\textup{\ding{46}}}\)
\(\)
\(\newcommand{\ElemA}{\circ}\)
\(\newcommand{\ElemB}{\bullet}\)
\(\)
\(\newcommand{\AxiomMarg}[1]{\makebox{}\hfill(\Blue{#1})}\)
\(\newcommand{\Comment}[1]{\makebox{}\hfill\Blue{#1}}\)
\(\)
\(\newcommand{\DLZ}{\mathit{DL}(\bbZ)}\)
\(\newcommand{\DLQ}{\mathit{DL}(\bbQ)}\)
\(\newcommand{\EUF}{\mathit{EUF}}\)
\(\newcommand{\TEUF}{\ThI{\mathit{EUF}}}\)
\(\newcommand{\LIA}{\mathit{LIA}}\)
\(\newcommand{\TLIA}{\ThI{\mathit{LIA}}}\)
\(\newcommand{\TNRA}{\ThI{\mathit{NRA}}}\)
\(\newcommand{\TNIA}{\ThI{\mathit{NIA}}}\)
\(\newcommand{\LRA}{\mathit{LRA}}\)
\(\newcommand{\TLRA}{\ThI{\mathit{LRA}}}\)
\(\newcommand{\IDL}{\mathit{IDL}}\)
\(\newcommand{\RDL}{\mathit{RDL}}\)
\(\newcommand{\EUFModels}{\mathrel{\models_{\TEUF}}}\)
\(\newcommand{\EUFModelsNot}{\mathrel{{\not\models}_{\TEUF}}}\)
\(\newcommand{\LIAModels}{\mathrel{\models_{\LIA}}}\)
\(\newcommand{\LIANotModels}{\mathrel{\not\models_{\LIA}}}\)
\(\newcommand{\LIAEntails}{\mathrel{\models_{\LIA}}}\)
\(\newcommand{\IDLEntails}{\mathrel{\models_{\IDL}}}\)
\(\newcommand{\NIAModels}{\mathrel{\models_{\TNIA}}}\)
\(\newcommand{\Div}[2]{{{#1}\mid{#2}}}\)
\(\)
\(\newcommand{\Sort}{s}\)
\(\newcommand{\SortI}[1]{s_{#1}}\)
\(\newcommand{\Sorts}{S}\)
\(\newcommand{\Func}{f}\)
\(\newcommand{\Funcs}{F}\)
\(\newcommand{\Pred}{p}\)
\(\newcommand{\Preds}{P}\)
\(\newcommand{\SortName}[1]{\textsf{#1}}\)
\(\)
\(\newcommand{\Var}{x}\)
\(\newcommand{\Vars}{X}\)
\(\newcommand{\BVar}{a}\)
\(\newcommand{\BVars}{\mathcal{B}}\)
\(\newcommand{\Val}{v}\)
\(\)
\(\newcommand{\DomOf}[1]{D_{#1}}\)
\(\)
\(\newcommand{\Term}{t}\)
\(\newcommand{\TermI}[1]{t_{#1}}\)
\(\newcommand{\TermP}[1]{t'}\)
\(\newcommand{\Atom}{A}\)
\(\)
\(\)
\(%\)
\(% EUF\)
\(%\)
\(\newcommand{\UFEq}{\equiv}\)
\(\newcommand{\UFEqP}{\mathrel{\equiv'}}\)
\(\newcommand{\UFEqNot}{\not\equiv}\)
\(\newcommand{\UFNeq}{\not\equiv}\)
\(\)
\(\)
\(\)
\(%\)
\(% Arithmetics\)
\(%\)
\(\newcommand{\IntsSort}{\textrm{Int}}\)
\(\newcommand{\IntsSig}{\SigI{\textrm{Int}}}\)
\(\newcommand{\RealsSort}{\textrm{Real}}\)
\(\newcommand{\Mul}{\mathbin{*}}\)
\(\)
\(%\)
\(% Arrays\)
\(%\)
\(\newcommand{\IndexSort}{\SortName{idx}}\)
\(%\newcommand{\IndexSort}{\SortName{index}}\)
\(\newcommand{\ElemSort}{\SortName{elem}}\)
\(%\newcommand{\ArraySort}{\SortName{array}}\)
\(\newcommand{\ArraySort}{\SortName{arr}}\)
\(\newcommand{\ArrSig}{\Sigma_{\mathit{arrays}}}\)
\(\newcommand{\ArrE}[1]{\textrm{a}_{#1}}\)
\(\)
\(\)
\(\newcommand{\TArrays}{\ThI{\mathit{arrays}}}\)
\(\newcommand{\TArraysExt}{\ThI{\mathit{arrays}}^{=}}\)
\(\newcommand{\ArrModels}{\mathrel{{\models_\mathit{arrays}}}}\)
\(\)
\(\)
\(%\)
\(% Theories of Lisp-like lists\)
\(%\)
\(\newcommand{\ThCons}{\ThI{\textrm{cons}}}\)
\(\newcommand{\ThConsAcyclic}{\ThI{\textrm{cons+}}}\)
\(\newcommand{\SigCons}{\SigI{\textrm{cons}}}\)
\(\newcommand{\Cons}{\FuncName{cons}}\)
\(\newcommand{\Car}{\FuncName{car}}\)
\(\newcommand{\Cdr}{\FuncName{cdr}}\)
\(\newcommand{\LAtom}{\PredName{atom}}\)
\(% Sorted version additions\)
\(\newcommand{\ListSort}{\SortName{list}}\)
\(\newcommand{\Nil}{\FuncName{nil}}\)
\(\newcommand{\Length}{\FuncName{length}}\)
\(\)
\(\)
\(\newcommand{\BVT}{\ThI{\mathsf{BV}}}\)
\(\newcommand{\BVSig}{\SigI{\mathsf{BV}}}\)
\(\newcommand{\BVS}[1]{\SortName{[}#1\SortName{]}}\)
\(%\newcommand{\BVS}[1]{[{#1}]}\)
\(\newcommand{\BVAdd}[1]{\mathbin{{+}_{\BVS{#1}}}}\)
\(\newcommand{\BVLE}[1]{\mathbin{{\le}_{\BVS{#1}}}}\)
\(\newcommand{\BVGE}[1]{\mathbin{{\ge}_{\BVS{#1}}}}\)
\(\newcommand{\BVSL}[1]{\mathbin{{\ll}_{\BVS{#1}}}}\)
\(\newcommand{\BVTermB}[1]{\hat{t}_{(#1)}}\)
\(%\newcommand{\BVTermBI}[2]{\hat{t}_{#1}^{(#2)}}\)
\(\newcommand{\BVAtom}{\hat{A}}\)
\(\newcommand{\BVXB}[1]{\hat{x}_{(#1)}}\)
\(\newcommand{\BVYB}[1]{\hat{y}_{(#1)}}\)
\(\newcommand{\BVVar}[1]{\hat{x}_{(#1)}}\)
\(\)
\(\)
\(% SMTLIB logics\)
\(\newcommand{\SMTLIBLogic}[1]{\textrm{#1}}\)
\(\newcommand{\QFUF}{\SMTLIBLogic{QF\_UF}}\)
\(\newcommand{\QFLIA}{\SMTLIBLogic{QF\_LIA}}\)
\(\newcommand{\QFUFLRA}{\SMTLIBLogic{QF\_UFLRA}}\)
\(\newcommand{\SMTLIBLIA}{\SMTLIBLogic{LIA}}\)
\(\)
\(\newcommand{\CG}[1]{G_{#1}}\)
\(\newcommand{\DiffEdge}[1]{\overset{#1}{\longrightarrow}}\)
\(\)
\(\newcommand{\FuncName}[1]{\textsf{#1}}\)
\(\newcommand{\PredName}[1]{\textsf{#1}}\)
\(\newcommand{\ReadF}{\FuncName{read}}\)
\(\newcommand{\Read}[2]{\ReadF(#1,#2)}\)
\(\newcommand{\WriteF}{\FuncName{write}}\)
\(\newcommand{\Write}[3]{\WriteF(#1,#2,#3)}\)
\(\)
\(\newcommand{\Abs}[1]{\alpha_{#1}}\)
\(\)
\(\newcommand{\Expl}[1]{\textit{explain}(#1)}\)
\(\)
\(\newcommand{\SMTAssertF}{\textsf{assert}}\)
\(\newcommand{\SMTAssert}[1]{\SMTAssertF(#1)}\)
\(\)
\(\newcommand{\UFRoot}{\textit{parent}}\)
\(\newcommand{\UFRootOf}[1]{{#1}.\UFRoot}\)
\(\newcommand{\UFRank}{\textit{rank}}\)
\(\newcommand{\UFRankOf}[1]{{#1}.\UFRank}\)
\(\newcommand{\UFFind}[1]{\textsf{find}(#1)}\)
\(\newcommand{\UFMerge}[2]{\textsf{merge}(#1,#2)}\)
\(\)
\(\newcommand{\CCPending}{\textit{pending}}\)
\(\)
\(\)
\(%\)
\(% Theory solver interface\)
\(%\)
\(\newcommand{\TSinit}[1]{\mathop{init}(#1)}\)
\(\newcommand{\TSassert}[1]{\mathop{assert}(#1)}\)
\(\newcommand{\TSretract}{\mathop{retract}()}\)
\(\newcommand{\TSisSat}{\mathop{isSat}()}\)
\(\newcommand{\TSgetModel}{\mathop{getModel}()}\)
\(\newcommand{\TSgetImplied}{\mathop{getImplied}()}\)
\(\newcommand{\TSexplain}[1]{\mathop{explain}(#1)}\)
\(\)
\(\)
\(\newcommand{\VarsOf}[1]{\mathop{vars}(#1)}\)
\(\)
\(\newcommand{\Dist}[1]{\mathit{dist}(#1)}\)
\(%\newcommand{\Dist}[1]{\mathit{dist}(#1)}\)
\(\)
\(%\)
\(% Nelson-Oppen\)
\(%\)
\(\newcommand{\TComb}{\cup}\)
\(\newcommand{\NOShared}[1]{\mathop{\textrm{shared}}(#1)}\)
\(\newcommand{\NOPart}{P}\)
\(\newcommand{\NOPartI}[1]{P_{#1}}\)
\(%\newcommand{\NOEq}{\mathrel{\approx}}\)
\(%\newcommand{\NOEqNot}{\mathrel{\not\approx}}\)
\(\newcommand{\NOEq}{\mathrel{{\equiv_{P}}}}\)
\(%\newcommand{\NOEq}{\stackrel{\NOPart}{\equiv}}\)
\(\newcommand{\NOEqNot}{\mathrel{\not\equiv_{\NOPart}}}\)
\(%\newcommand{\NOEqNot}{\stackrel{\NOPart}{\not\equiv}}\)
\(\newcommand{\NOArr}{\mathop{arr}(P)}\)
\(\newcommand{\NOArrI}[1]{\mathop{arr}(P_{#1})}\)
\(\)
\(%\)
\(% Example formulas in Nelson-Oppen part\)
\(%\)
\(\newcommand{\NOF}{\phi}\)
\(%\newcommand{\NOFA}{\phi_1}\)
\(%\newcommand{\NOFB}{\phi_2}\)
\(%\newcommand{\NOTA}{\ThI{1}}\)
\(%\newcommand{\NOTB}{\ThI{2}}\)
\(\newcommand{\NOFEUF}{\phi_\mathit{EUF}}\)
\(\newcommand{\NOFLIA}{\phi_\mathit{LIA}}\)
\(\newcommand{\NOFLRA}{\phi_\mathit{LRA}}\)
\(\newcommand{\NOFCons}{\phi_\textup{cons}}\)
\(\)
\(%\newcommand{\Asgn}{\mathrel{:=}}\)
\(\newcommand{\Asgn}{\mathrel{\leftarrow}}\)
\(\)
\(%\newcommand{\Engl}[1]{(engl.\ #1)}\)
\(\)
\(\newcommand{\Ack}[1]{\mathop{ack}(#1)}\)
\(\newcommand{\VVar}[1]{v_{#1}}\)
\(\newcommand{\FVar}[2]{{#1}_{#2}}\)
\(\newcommand{\PVar}[2]{{#1}_{#2}}\)
\(\newcommand{\Flat}{{\phi_\textrm{flat}}}\)
\(\newcommand{\Cong}{{\phi_\textrm{cong}}}\)
\(\)
\(\newcommand{\In}{\mathit{in}}\)
\(\newcommand{\Out}{\mathit{out}}\)
\(\)
\(\newcommand{\SubType}{\FuncName{subtype}}\)
\(\)
\(%\)
\(% Fourier-Motzkin elimination\)
\(%\)
\(\newcommand{\FM}{\phi}\)
\(\newcommand{\FMup}{\phi^\textrm{up}}\)
\(\newcommand{\FMlo}{\phi^\textrm{low}}\)
\(%\newcommand{\FMup}{\phi^{\le}}\)
\(%\newcommand{\FMlo}{\phi^{\ge}}\)
\(\newcommand{\FMindep}{\phi^{\ast}}\)
\(\newcommand{\Nup}{n^\textrm{up}}\)
\(\newcommand{\Nlo}{n^\textrm{low}}\)
\(%\newcommand{\Nup}{n^{\le}}\)
\(%\newcommand{\Nlo}{n^{\ge}}\)
\(\newcommand{\Rup}[1]{A^\textrm{up}_{#1}}\)
\(\newcommand{\Rlo}[1]{A^\textrm{low}_{#1}}\)
\(%\newcommand{\Rup}[1]{A^{\le}_{#1}}\)
\(%\newcommand{\Rlo}[1]{A^{\ge}_{#1}}\)
\(%\newcommand{\FMless}{\mathrel{\triangleleft}}\)
\(%\newcommand{\FMmore}{\mathrel{\triangleright}}\)
\(\)
\(\)
\(\)
\(\newcommand{\ProblemName}[1]{\textup{#1}}\)
\(\newcommand{\ATM}{A_\textup{TM}}\)
\(\newcommand{\PCP}{\ProblemName{PCP}}\)
\(\newcommand{\MPCP}{\ProblemName{MPCP}}\)
\(\newcommand{\PCPAst}{\star}\)
\(\)
\(\newcommand{\Eps}{\varepsilon}\)
\(\)
\(\newcommand{\List}[1]{[#1]}\)
\(\newcommand{\Strings}[1]{\{#1\}^\star}\)
\(\newcommand{\StringsOver}[1]{{#1}^\star}\)
\(\newcommand{\SigmaStrings}{\Sigma^\star}\)
\(\newcommand{\GammaStrings}{\Gamma^\star}\)
\(\newcommand{\Complement}[1]{\overline{#1}}\)
\(\)
\(\)
\(%\)
\(% SSA example\)
\(%\)
\(\newcommand{\In}{\mathit{in}}\)
\(\newcommand{\Out}{\mathit{out}}\)
\(\)
\(%\)
\(%\)
\(%\)
\(\newcommand{\DA}{♠}\)
\(\newcommand{\DB}{♣}\)
\(\newcommand{\DC}{♥}\)
\(\newcommand{\DD}{♦}\)
\(\)
\(%\)
\(% Jobshop example\)
\(%\)
\(\newcommand{\JSJobs}{J}\)
\(\newcommand{\JSJob}[1]{J_{#1}}\)
\(\newcommand{\JSForm}{\phi(\JSJobs)}\)
\(\newcommand{\JSNofTasks}[1]{N_{#1}}\)
\(\newcommand{\JSTask}[2]{T_{#1,#2}}\)
\(\newcommand{\JSMach}[2]{M_{#1,#2}}\)
\(\newcommand{\JSDur}[2]{D_{#1,#2}}\)
\(\newcommand{\JSStart}[2]{s_{#1,#2}}\)
\(\newcommand{\JSBudget}{\mathit{budget}}\)
A Theory Solver for Equality with Uninterpreted Functions
We now present a decision procedure for quantifier-free conjunctions of \( \TEUF \)-literals.
The explanation is only a high-level sketch; details, optimizations and analysis can be found in the references given later.
Recall that the theory \( \TEUF \) allows arbitrary interpretations for
the function symbols as long as they are functions.
That is, the function congruence rule
\( (v_1 = w_1) \land … \land (v_n = w_n) \Implies f(v_1,…,v_n)=f(w_1,…,w_n) \),
where the \( v \)’s and \( w \)’s are values, must always hold.
We can lift this rule to the level of symbolic terms as follows.
Assume that we have an equivalence relation \( \UFEq \) over a set of terms.
We say that the relation is closed under the function congruence rule if
\[(t_1 \UFEq u_1) \land … \land (t_n \UFEq u_n) \Implies f(t_1,…,t_n) \UFEq f(u_1,…,u_n)\]
holds whenever \( t_1,…,t_n,u_1,…u_n,f(t_1,…,t_n),f(u_1,…,u_n) \) are terms in the set.
If \( (t_1 \UFEq u_1) \land … \land (t_n \UFEq u_n) \) holds but
\( f(t_1,…,t_n) \UFNeq f(u_1,…,u_n) \),
then we can apply the rule and
obtain a new equivalence relation which is the same as \( \UFEq \)
except that the classes of \( f(t_1,…,t_n) \) and \( f(u_1,…,u_n) \) are merged.
Example
The equivalence relation
$${\UFEq_1} = \Set{\Set{x_1,x_2,x_3},\Set{f(x_1),f(x_3)},\Set{g(x_2,f(x_3))},\Set{g(x_2,f(x_1))}}$$
is not closed under the function congruence rule
as \( f(x_1) \UFEq_1 f(x_3) \) but \( g(x_2,f(x_3)) \UFNeq_1 g(x_2,f(x_1)) \).
Applying the rule gives the new relation
$${\UFEq_2} = \Set{\Set{x_1,x_2,x_3},\Set{f(x_1),f(x_3)},\Set{g(x_2,f(x_3)),g(x_2,f(x_1))}}$$
which is closed under the rule.
The main idea of the algorithm is now quite simple:
maintain an equivalence relation over the terms in the formula,
and perform the following.
Start with the discrete relation (each term is only equivalent to itself).
When a new equality \( t_1 \Eq t_2 \) are asserted,
merge the equivalence classes containing \( t_1 \) and \( t_2 \), and
apply the function congruence closure rule until the relation is closed under it.
Remember the asserted disequalities \( t_1 \Neq t_2 \), and
check whether they are violated when equivalence classes are merged.
The algorithm and its variants are commonly called the congruence closure algorithm.
Implementing equivalence classes
Equivalence classes with merges can be implemented with, e.g.,
the union-find data structure (recall the Aalto course “CS-A1140 Data Structures and Algorithms”)
which maintains the equivalence classes in disjoint trees: two elements are equivalent if they belong to the same tree.
To represent the trees, one only needs to associate each element with
a \( \UFRoot \) pointer initialized to point to the element itself, and
a \( \UFRank \), initialized to 0, to keep the constructed tree balanced.
def \( \UFFind{e} \): // Find the root of the tree containing \( e \)
while \( \UFRootOf{e} \neq e \):
\( e \Asgn \UFRootOf{e} \)
return \( e \)
def \( \UFMerge{e_1}{e_2} \): // Merge the classes of \( e_1 \) and \( e_2 \)
\( r_1 \Asgn \UFFind{e_1} \), \( r_2 \Asgn \UFFind{e_2} \)
if \( r_1 = r_2 \): return
if \( \UFRankOf{r_1} < \UFRankOf{r_2} \):
\( \UFRootOf{r_1} \Asgn r_2 \)
else if \( \UFRankOf{r_1} > \UFRankOf{r_2} \):
\( \UFRootOf{r_2} \Asgn r_1 \)
else:
\( \UFRootOf{r_1} \Asgn r_2 \)
\( \UFRankOf{r_2} \Asgn \UFRankOf{r_2}+1 \)
Example
Assume the elements \( e_1,…,e_5 \).
Initially, each element is in its own class.
Thus \( e_i \UFEqNot e_j \) whenever \( i \neq j \).
Execute \( \UFMerge{e_1}{e_2} \).
Execute \( \UFMerge{e_5}{e_4} \)
Execute \( \UFMerge{e_1}{e_5} \)
Now \( \UFFind{e_1} = e_4 = \UFFind{e_5} \)
and thus \( e_1 \UFEq e_5 \).
Asserting equality and disequality atoms
The core part of our \( \TEUF \)-solver is to maintain the equivalence classes
between the terms, and their sub-terms,
when equalities and disequalities are asserted.
Initially, each term is in its own equivalence class.
When an equality between two terms is asserted, the algorithm
merges the corresponding classes,
applies the congruence rule until the equivalence relation becomes closed under it, and
checks if a recorded disequality is violated.
When a disequality between two terms is asserted, the solver
def \( \SMTAssert{t \Eq u} \):
\( \CCPending \Asgn \Set{\Pair{t}{u}} \)
while \( \CCPending \) not empty:
pop a \( \Pair{v}{w} \) from \( \CCPending \)
if \( \UFFind{v}=\UFFind{w} \): continue
\( \UFMerge{v}{w} \)
for each pair \( v' \), \( w' \) such that
1. \( v' \Abbrv f(v'_1,...,v'_n) \) and \( w' \Abbrv f(w'_1,...,w'_n) \),
2. \( \UFFind{v'_1}=\UFFind{w'_1},..., \)
\( \UFFind{v'_n}=\UFFind{w'_n} \), and
3. \( \UFFind{v'} \neq \UFFind{w'} \),
add \( \Pair{v'}{w'} \) in \( \CCPending \)
for each recorded \( v \Neq w \):
if \( \UFFind{v}=\UFFind{w} \): return false
return true
def \( \SMTAssert{\neg(t \Eq u)} \):
if \( \UFFind{t}=\UFFind{u} \): return false
record \( t \Neq u \)
return true
Example
Consider the conjunction
\[{f(f(f(x))) \Eq x} \land {f(f(f(f(f(x))))) \Eq x} \land {f(x) \Neq x}\]
and, for clarity, use the abbreviations
\( t_1 \Abbrv f(x) \), \( t_2 \Abbrv f(f(x)) \Abbrv f(t_1) \), \( t_3 \Abbrv f(t_2) \), \( t_4 \Abbrv f(t_3) \), \( t_5 \Abbrv f(t_4) \) for the component terms.
The parse tree of the formula can be drawn as
Initially, the equivalence classes are
\( \Set{x},\Set{t_1},\Set{t_2},\Set{t_3},\Set{t_4},\Set{t_5} \)
and the union-find data structure looks like
Asserting \( f(f(f(x))) \Eq x \) merges \( t_3 \) and \( x \):
\( \Set{x,t_3},\Set{t_1},\Set{t_2},\Set{t_4},\Set{t_5} \)
\( x \UFEq t_3 \) implies \( {t_1 \Abbrv f(x)} \UFEq {t_4 \Abbrv f(t_3)} \):
\( \Set{x,t_3},\Set{t_1,t_4},\Set{t_2},\Set{t_5} \)
\( t_1 \UFEq t_4 \) implies \( {t_2 \Abbrv f(t_1)} \UFEq {t_5 \Abbrv f(t_4)} \):
\( \Set{x,t_3},\Set{t_1,t_4},\Set{t_2,t_5} \)
Asserting \( f(f(f(f(f(x))))) \Eq x \) merges \( t_5 \) and \( x \):
\( \Set{x,t_3,t_2,t_5},\Set{t_1,t_4} \)
\( x \UFEq t_2 \) implies \( t_1 = f(x) \UFEq t_3=f(t_2) \):
\( \Set{x,t_3,t_2,t_5,t_1,t_4} \)
Now we see that \( {t_1 \Abbrv f(x)} \UFEq x \)
and
thus \( f(x) \Eq x \) should hold.
However, \( f(x) \Neq x \) is a conjunct in the original conjunction
and
therefore the conjunction is unsatisfiable.
When actually implementing the above methods,
(i) the equivalence classes can be implemented with the union-find data structure,
(ii) finding congruent terms can be implemented with a hash table, and
(iii) backtracking equals to undoing the merges (and recomputing hash values).
When a conjunction is satisfiable, constructing a model for it is easy:
just assign the elements in each equivalence class into a distinct value.
Theory-Implied Literals
Propagation of positive atoms \( t_1 \Eq t_2 \) is fast:
at each merge, check if \( t_1 \) and \( t_2 \) are merged to the same class
if yes, report \( t_1 \Eq t_2 \) as an implied literal.
Propagating negative literals requires more work:
When asserting \( \neg(t_1 \Eq t_2) \) and \( t_1 \UFEqNot t_2 \) holds,
report, for each atom \( t’_1 \Eq t’_2 \) with \( t’_1 \UFEq t_1 \) and \( t’_2 \UFEq t_2 \), the implied literal \( \neg(t’_1 \Eq t’_2) \)
When merging two classes, find atoms of form \( t’_1 \Eq t’_2 \) for which
(i) \( t’_1 \) or \( t’_2 \) are in the merged class, and
(ii) \( t’_1 \UFEq t_1 \) and \( t’_2 \UFEq t_2 \) hold for some recorded disequality \( t_1 \Neq t_2 \),
and report the implied literal \( \neg(t’_1 \Eq t’_2) \).
Example
Consider the formula
\[\neg({x \Eq y} \land {y \Eq z}) \land ({y \Eq f(z)} \Implies {g(x) \Eq g(f(z))} \land {z \Eq f(z)})\]
Initially all its terms are in their own equivalence classes and
\( {\UFEq_0} = \Set{\Set{x},\Set{g(x)},\Set{y},\Set{z},\Set{f(z)},\Set{g(f(z))}} \).
Consider the following sequence of literal assertions
The CDCL SAT solver asserts \( x \Eq y \) into the theory solver,
which updates the equivalence relation to
\( {\UFEq_1} = \Set{\Set{x,y},\Set{g(x)},\Set{z},\Set{f(z)},\Set{g(f(z))}} \).
The CDCL SAT solver asserts \( \neg(y \Eq z) \) into to theory solver,
which does not update the equivalence relation but records
the disequality.
Note that \( \neg(x \Eq z) \) would be implied at this point
if it were an atom in the formula.
The CDCL SAT solver asserts \( y \Eq f(z) \) into the theory solver,
which updates the equivalence relation to
\( {\UFEq_2} = \Set{\Set{x,y,f(z)},\Set{g(x),g(f(z))},\Set{z}} \).
Note that as \( x \) and \( f(z) \) are in the same class, the classes of
\( g(x) \) and \( g(f(z)) \) are merged as well.
The theory solver reports the implied literals
\( g(x) \Eq g(f(z)) \), and
\( \neg(z \Eq f(z)) \) as \( f(z) \UFEq_2 y \) and \( \neg(y \Eq z) \) is recorded.
To produce explanations, one can remember in a “reason graph”
each equality and disequality assertion, and
for each implied literal, the immediate reason for the implication.
The reasons can then be recursively expanded to get the explanation consisting only of assertions.
Example: Continues the previous one
For the previous example, the reason graph could be
The explanation for \( g(x) \Eq g(f(z)) \) is obtained by
explaining the immediate reason \( x \UFEq f(z) \).
This is done by explaining the path between \( x \) and \( f(z) \).
The result is \( (x \Eq y) \land (y \Eq f(z)) \).
The explanation for \( \neg(z \Eq f(z)) \) is \( y \Neq z \) conjuncted with the explanation for \( f(z) \UFEq y \), i.e., the assertion \( y \Eq f(z) \).
Some further reading
Classic papers on congruence closure:
A contemporary approach giving fast algorithms for congruence closure as
well as an extension to integer offsets, allowing atoms of form \( x = y + k \) for integer constants \( k \):
Congruence closure in a theorem proving setting: