<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta>
      <journal-title-group>
        <journal-title>Satisfiability Modulo Theories, August</journal-title>
      </journal-title-group>
    </journal-meta>
    <article-meta>
      <title-group>
        <article-title>A Simple Proof Format for SMT</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Jochen Hoenicke</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Tanja Schindler</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Department of Computer Science, University of Freiburg</institution>
          ,
          <country country="DE">Germany</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2022</year>
      </pub-date>
      <volume>1</volume>
      <fpage>1</fpage>
      <lpage>12</lpage>
      <abstract>
        <p>We present a simple resolution-based proof format targeted for SMT. The proof format uses a syntax similar to SMT-LIB terms. The resolution rule is its only proof rule with premises; all other rules are axioms proving tautological clauses. The format aims to be solver-independent by only including a minimal complete set of axioms while still being able to express proofs succinctly. Most of its axioms are purely syntactic; only for arithmetic reasoning, some axioms with side conditions are used for succinct reasoning with linear (in)equalities. The format can be extended with solver-specific rules, which can then either be treated as trusted axioms, or, better, replaced by their low-level proof. The format has been implemented in the solver SMTInterpol and the solver produces proofs for all benchmarks it can solve in the combinations of the theories of equality, linear arithmetic, arrays and datatypes. There is also a stand-alone proof checker for this format.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;SMT</kwd>
        <kwd>proofs</kwd>
        <kwd>proof format</kwd>
        <kwd>resolution</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>SMT solvers have become an integral part of many modern verification techniques. They are
used to prove the absence of errors in complex systems that cannot be verified by hand. This
begs the question whether the solvers themselves are correct.</p>
      <p>
        Many SMT solvers can support their answer on the satisfiability problem of a formula by
providing either a model for a satisfiable formula, or a proof for an unsatisfiable formula. The
SMT-LIB standard [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] already prescribes the form of models. Models are relatively easy to
verify, at least for quantifier-free formulas, by evaluating the formula using the model’s function
definitions. The annual competition of SMT solvers, the SMT-COMP, includes a model validation
track since 2019, where models are checked by an independent tool.1 For unsatisfiable formulas,
many solvers can already produce proofs in some solver-specific format, but no standardized
proof format exists so far.
      </p>
      <p>In this paper we present a very simple but expressive proof format that we propose as a
candidate for such a standard. Our proof format uses the resolution rule known from SAT
proofs and combines it with axioms for SMT theories. We propose to use a minimal complete
set of axioms, and the idea is that a solver needs to explain its theory lemmas using only these
axioms. An important idea is that even the meaning of the built-in logical symbols like not and
or is given by axioms that correspond to the Tseitin transformation. Thus, even the conversion
into conjunctive normal form (CNF) can be explained in this format. By implementing the
proof format in SMTInterpol, we have shown that despite the minimality of the axiom set, the
overhead of generating proofs is manageable (it is linear in the run-time of the solver).</p>
      <p>We claim that our proof format solves the following goals: (1) it is easy and fast to verify,
(2) it avoids solver-specific rules, (3) it supports several reasoning techniques, from equality
rewriting to symmetry breaking, (4) it enables short proofs that are linear in the number of
reasoning steps the solver took.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Basic Notation</title>
      <p>
        We use the SMT-LIB [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] syntax for terms. SMT-LIB is based on sorted first-order logic with the
sort Bool representing Boolean values. A function symbol f has an arity  1 × · · · ×   → 
(determined by the theory or by a function declaration) and if 1, . . . ,  are terms of type
 1, . . . ,   respectively, then (f 1 ...) is an (SMT-LIB) term of type  . SMT-LIB formulas
are terms of type Bool. The logical operators are built-in function symbols and, or, =&gt;, etc. of
arity Bool × Bool → Bool. Similarly, the symbols true and false are function symbols of
arity Bool (no arguments) and thus also terms of type Bool.
      </p>
      <p>We use typewriter font for literal SMT-LIB terms,  stands for an SMT-LIB term and  for an
SMT-LIB formula (term of type Bool). We use the symbol f for an (uninterpreted or theory)
function symbol, the symbol  for variables, and  for SMT-LIB sorts. We use prf for proof
terms. In linear arithmetic, we use  for a polynomial.</p>
    </sec>
    <sec id="sec-3">
      <title>3. Proof Format</title>
      <p>Our proof format is a resolution proof that shows unsatisfiability by deriving the empty clause.
The leaves of the proof are input formulas and axioms. The only proof rule is the resolution
rule that proves from two given clauses a resolvent.</p>
      <p>{} ∪ 1 {¬} ∪ 2
1 ∪ 2
(res)
A clause is a set of literals, which is interpreted as the disjunction of these literals. A literal is a
positive or negated atomic formula. The core idea of our proof format is that atomic formulas
are exactly the SMT-LIB formulas, i.e., SMT-LIB terms of type Bool.</p>
      <p>As far as the proof format is concerned, the atomic formulas are opaque and even the built-in
SMT-LIB functions and, or, not have no predefined meaning. Instead the meaning is given by
axioms that can be seen as a set of theory lemmas for the core theory. For each SMT-LIB formula ,
there are the axioms (not+ ) : {(not ), }2 and (not- ) : {¬(not ), ¬}. Similarly,
the axioms (or- 0 1) : {¬(or 0 1), 0, 1}, (or+ 0 0 1) : {(or 0 1), ¬0}, and
(or+ 1 0 1) : {(or 0 1), ¬1} define the meaning of (or 0 1).</p>
      <p>The syntax of proof terms is similar to the syntax of SMT-LIB terms. The simplest proof
term is an axiom, e.g., (not+ ). Moreover, for each assertion (assert ) in the SMT-LIB
2We write prf :  to denote that prf is an axiom stating the validity of the clause .
(set-option :produce-proofs true)
(set-logic QF_UF)
(declare-fun q1 () Bool)
(declare-fun q2 () Bool)
(assert (or (not q1) q2))
(assert q1)
(assert (not q2))
(check-sat)
(get-proof)
unsat
(res q1 (assume q1) (res q2
(res (not q1)
(res (or (not q1) q2)
(assume (or (not q1) q2))
(or- (not q1) q2))
(not- q1))
(res (not q2) (assume (not q2))</p>
      <p>(not- q2))))
assume
{(or (not q1) q2)}</p>
      <p>(or- (not q1) q2)
{¬(or (not q1) q2), (not q1), q2}</p>
      <p>(not- q1)
{(not q1), q2} {¬(not q1), ¬q1}
assume
{q1}
{q2, ¬q1}
{}
{¬q1}</p>
      <p>assume
{(not q2)}</p>
      <p>(not- q2)
{¬(not q2), ¬q2}
{¬q2}
input, the proof term (assume ) proves the unit clause {}. The concrete syntax for the
resolution rule is (res  prf 1 prf 2) where  is the pivot atom and prf 1 and prf 2 are the
proof terms for the subproofs. Figure 1 shows a simple proof for the unsatisfiabilty of the
assertions (or (not q1) q2), q1, (not q2), where q1, q2 are constants of type Bool. Each
proof term proves a clause and the whole proof of unsatisfiability is correct if it proves the
empty clause.</p>
      <p>Sharing Proofs and Subterms. Proofs often use the same intermediate clause several times.
For a succinct representation of such proofs, repeated subproofs may be bound to variables, e.g.,
the syntax</p>
      <p>(let-proof ((C (res (not q) (assume (not q)) (not- q)))) prf )
binds the proof of {¬q} to the variable C. This variable may then be used in prf , i.e., it may
be given as argument to res applications whenever a resolution with this clause should be
performed. Note that the syntax is similar to the let-syntax for SMT-LIB terms. Furthermore
the proof format also supports the let binder with the identical syntax as for SMT-LIB terms
to bind terms to variables that are used in axioms or as pivot atoms multiple times. The latter
is important for keeping the proof size down, because large subterms may naturally appear
several times, for example in proofs where a large input formula is converted into CNF. In fact,
in most proofs produced by our solver, every subterm of every asserted term is bound to a
variable because it is used multiple times in the proof. In general, proofs grow exponentially if
let terms are expanded.</p>
      <p>In our proof format, let and let-proof are syntactic sugar and equivalent to their expanded
form where every variable is replaced by its definition. As an example,</p>
      <p>(let ((x (not q2))) (res x (assume x) (not- q2)))
is a valid subproof because x is implicitly expanded to (not q2) and the pivot atom matches
the negated atom in the clause (not- q2) : {¬(not q2), ¬q2}. There is no proof rule for let
expansion as both the expanded and contracted term are seen as the same term. Internally, our
proof checker expands all let terms, using a DAG representation to avoid exponential blow-up.</p>
      <p>The two diferent binders let-proof for proofs and let for terms simplify parsing. If let
would be used for both, then symbols like res, and+, etc. would need to become predefined
symbols and must not be used as user-defined symbols in benchmarks. By using two diferent
binders, it is clear from the context whether a term is a proof term or an SMT-LIB term.
Defining Functions. In proofs it may be desirable to have prover-defined auxiliary functions
that do not appear in the input problem. Our proof format uses the syntax</p>
      <p>((define-fun f ((1  1) ...(  )) ) prf )
where f is a function symbol and  the defining term that uses the variables 1, . . . ,  of
type  1, . . . ,  . The whole proof term proves the same clause as its subproof prf proves. The
subproof prf may use f as if it was a user-defined function. In particular, prf can contain the
axioms cong and expand from the core theory.</p>
      <p>Oracles. Sometimes it is useful to state a fact without proving it, e.g., because a rigorous proof
requires new axioms (when extending the format to a new theory) or because a simplification
step should be expressed in proofs before reducing it to the axioms of the theory at a later time.
Our proof format supports an oracle axiom with the following syntax.</p>
      <p>(oracle ±
1 . . . ±
 Attributes)
Here ± is + (positive literal) or - (negated literal) and Attributes is a user-defined list of
keyvalue pairs of the form :key value, where :key is an identifier prefixed by a colon and value
an arbitrary s-expression or empty. The oracle itself proves the clause {(¬) 1, . . . , (¬) }
where the literal  is negated if and only if  was prefixed by - in the axiom.</p>
    </sec>
    <sec id="sec-4">
      <title>4. Axioms</title>
      <p>To provide meaning for the built-in SMT-LIB functions of the core theory, several axioms are
defined, see Figure 2 for a complete list. For each logical operator there is an introduction
axiom, e.g., and+, and an elimination axiom, e.g., and-. These can be used to eliminate or
=-1 : {¬(= 0 1), 0, ¬1}
=+2 : {(= 0 1), ¬0, ¬1} =-2 : {¬(= 0 1), ¬0, 1}
xor+ : {(xor 1), (xor 2), ¬(xor 3)} xor- : {¬(xor 1), ¬(xor 2), ¬(xor 3)}
where 1,2,3 are lists of formulas and each formula occurs an even number in total
forall+ : {(forall ((  )) ), ¬(let (( (choose (  ) (not )))) )}
forall- : {¬(forall ((  )) ), (let (( )) )}
exists+ : {(exists ((  )) ), ¬(let (( )) )}
exists- : {¬(exists ((  )) ), (let (( (choose (  ) ))) )}
refl : {(=  )}</p>
      <p>symm : {(= 0 1), ¬(= 1 0)}
trans : {(= 0 ), ¬(= 0 1), . . . , ¬(= − 1 )}
cong : {(= (f 0 . . . ) (f ′0 . . . ′)), ¬(= 0 ′0), . . . , ¬(=  ′)}
=+ : {(= 0 . . . ), ¬(= 0 1), . . . , ¬(= − 1 )}
=- : {¬(= 0 . . . ), (=  )}
distinct+ : {(distinct 0 . . . ), (= 0 1), . . . , (= 0 ), . . . , (= − 1 )}
distinct- : {¬(distinct 0 . . . ), ¬(=  )}
ite1 : {(= (ite 0 1 2) 1), ¬0} ite2 : {(= (ite 0 1 2) 2), 0}
del! : {(= (!  . . .) )}
expand : {(= (f 0 . . . ) (let ((0 0). . .( )) ))}</p>
      <p>where f is defined by (define-fun f ((0  0)...(  )) )
introduce the corresponding operator into the formula by applying the resolution rule. The
axioms are written as application terms that take the instantiated terms as arguments, e.g.,
(and+ 0 1) : {(and 0 1), ¬0, ¬1}. The axioms and-, or+, =&gt;+, =-, distinct- take as
additional argument the value  (and ), a literal number between 0 and , e.g., (and- 0 0 1) :
{¬(and 0 1), 0}.</p>
      <p>Boolean equality in SMT-LIB corresponds to logical equivalence. We define corresponding
introduction and elimination axioms =+1 to =-2. These rules may only be used on terms of
type Bool and this has to be verified by the proof checker.</p>
      <p>Quantifiers are supported using the SMT-LIB 3.0 choose operator, which is Hilbert’s epsilon
operator. For brevity, the figure shows the axioms only for one variable, but they are also
supported for multiple variables, e.g., the axiom exists- is the following.</p>
      <p>(exists- ((1  1) . . . (  )) ) :
{¬(exists ((1  1) . . . (  )) ),
(let ((1 (choose (1  1) (exists ((2  2) . . . (  )) ))))
(let ((2 (choose (2  2) (exists ((3  3) . . . (  )) ))))
.
.
.</p>
      <p>(let (( (choose (  ) ))) )· · · ))}
The axioms from refl to distinct- are the axioms for the theory of equality. They can also be
used for Boolean equality (logical equivalence) and cong can also be used on built-in function
symbols like and or even = itself. The axioms ite1 and ite2 can be used for Boolean and
non-Boolean ite terms. The axiom del! states that adding annotations to an SMT-LIB term
does not change its meaning. Finally, the axiom expand can be used to expand user-defined
and prover-defined (see Section 3) function symbols.
4.1. Axioms for Linear Arithmetic
For linear arithmetic, purely syntactic rules come to their limit, for example, when proving
arithmetic operations on rationals like {(= (+ (/ 1.0 3.0) (/ 1.0 6.0)) (/ 1.0 2.0))}.
To ease the reasoning about arithmetic, our proof format has some built-in axioms with side
conditions that use addition and/or multiplication of rational numbers and polynomials.</p>
      <p>We use the SMT-LIB canonical form for numeric constants, with a slight alteration for
rationals. In SMT-LIB, the number 1 of type Real is represented as 1 in the logic LRA and as
1.0 in the logic LIRA. We use 1.0 in both logics. Similarly, we always represent fractions as (/
1.0 3.0) or (/ (- 2.0) 3.0) (like in SMT-LIB, fractions need to be reduced).</p>
      <p>We define a polynomial as a finite map from multisets of SMT-LIB terms to non-zero rational
coeficients. Each entry {1, . . . , } ↦→  of this map is a monomial, which is represented as
(*  1 . . . ) in SMT-LIB. In this representation,  can be omitted if  = 1 and  &gt; 0. The
multiplication symbol is omitted if it has only one argument. The terms 1, . . . ,  must not be
applications of + or * and they must not be numeric constants in canonical form. A polynomial
is either of type Real or Int and all terms in all multiset must be of the same type and all
coeficients must be integral if the polynomial is of type Int. The term representing a polynomial
is (+ 1 . . . ) where 1, . . . ,  are the monomial representations of the entries of the
map. A polynomial with a single entry in the map is represented by 1 and the empty map is
represented by 0 or 0.0. As an example, the polynomial {{x, x} ↦→ 2, {x} ↦→ 1, {} ↦→ 1} with
x of type Int is represented by the SMT-LIB term (+ (* 2 x x) x 1).</p>
      <p>A polynomial can have several representations that difer in the order of the terms, but each
SMT-LIB term can only be the representation of at most one polynomial. The sum 1 + 2 of
two polynomials 1, 2 is built by conjoining the maps, adding the rational constants if the same
multiset appears in both polynomials, and removing the entries whose sum of the constants
is zero. The product 1 · 2 is built by computing the sum of the products for each pair of
monomials. The product of two monomials is just the union of the multisets mapped to the
product of the rational constants. A polynomial of type Int can be cast to real by surrounding
each term in each multiset with a to_real application and converting the coeficients to real
by appending .0 to the constant. A polynomial is a constant, if it is zero (the empty map) or a
singleton map whose multiset is empty. Note that the representation of a constant polynomial
is the constant term in canonical form.</p>
      <p>Figure 3 shows the axioms for linear arithmetic. The first two axioms poly+ and poly*
can be used to simplify arithmetic terms in the input formula and have a side condition that
requires polynomial addition or multiplication, respectively. Note that the resulting polynomial
has to be given in the proof, as its SMT-LIB representation is not unique, e.g., the axioms
(poly+ (+ x y x) (+ (* 2 x) y)) and (poly+ (+ x y x) (+ y (* 2 x))) are both
valid and prove diferent clauses. The prover can choose the representation and the proof checker
checks that  is indeed a valid representation of the polynomial that is the sum or product of
1, . . . , . However, (poly+ (+ x y x) (+ x y x)) is not well-formed (a polynomial can
only have one entry for the multiset {}).</p>
      <p>The heart of our arithmetic proof is the axiom farkas that proves the unsatisfiability of the
conjunction of several literals, whose weighted sum yields a contradiction. A variant of Farkas’
lemma states that a set of inequalities  ≤  is unsatisfiable if and only if there is a vector
 = (1, . . . , ) with  ≥ 0,   = 0, and   &lt; 0. The axiom provides the coeficients
1, . . . , , e.g., (farkas 1 (&lt;= x (* 2 y))) 2 (&lt; y z) 1 (= (+ (* 2 z) 5) x)) is
a valid instance proving {¬(&lt;= x (* 2 y))), ¬(&lt; y z), ¬(= (+ (* 2 z) 5) x))},
because the inequalities sum up to the contradiction 5 &lt; 0 and x, y, z cancel out. It is allowed to
use both integer and real literals in the same instance of the axiom farkas and in that case the
weighted sum is computed after implicitly casting all integer polynomials to real.</p>
      <p>We found that farkas, trichotomy, total, and total-int together with the core axioms
for equality are complete for linear arithmetic in the sense that any valid disjunction of possibly
negated equalities and inequalities of linear polynomials can be proved using just these axioms.
The axiom farkas can prove clauses containing negated literals and the other three axioms
can be used to rewrite negated literals into their positive form. The axiom total-int can be
used to introduce arbitrary integer cuts, since 1 can be an arbitrary term.</p>
      <p>If an input term is not already a polynomial, the rules poly* and poly+ together with the
axiom cong can be used to rewrite it into a polynomial. To support arbitrary SMT-LIB input
formulas, we need a few more axioms to rewrite other operators like &gt;, &gt;=, -, /, div, mod, etc.
See the appendix for a complete list.</p>
    </sec>
    <sec id="sec-5">
      <title>5. Proofs in SMTInterpol</title>
      <p>Our solver SMTInterpol produces proofs in the proof format presented in this paper. The reader
is invited to experiment using our web interface for proof production and checking.3</p>
      <p>The solver itself proves a benchmark in three phases. In the first phase, the input formula
is simplified using equality rewriting and several solver-specific rewriting rules. The second
phase converts the input formula into conjunctive normal form (CNF), creating an internal
representation for every literal and adding auxiliary clauses. The third phase runs the DPLL( )
algorithm and generates theory lemmas, building the final resolution proof.
3See https://ultimate.informatik.uni-freiburg.de/smtinterpol/online/proof.html
(farkas 1 (&lt;=? 1 1′) . . .  (&lt;=?  ′)) : {¬(&lt;=? 1 1′), . . . , ¬(&lt;=?  ′)}
where  are positive integer constants, the weighted sum 1(1 − 1′) + · · · + ( − ′) is
a non-negative constant. &lt;=? stands for &lt;, &lt;=, or =, and if the weighted sum is zero, at least
one of the literals must be &lt;.</p>
      <p>(trichotomy 1 2) : {(&lt; 1 2), (= 1 2), (&lt; 2 1)}</p>
      <p>(total 1 2) : {(&lt;= 1 2), (&lt; 2 1)}
(total-int 1 ) : {(&lt;= 1 ), (&lt;=  + 1 1)}
where 1 has type Int,  is an integer constant in canonical form and  + 1 the same
integer constant increased by one in canonical form.</p>
      <p>In the first phase, the input term  is inductively rewritten into a simplified term ′. If proof
production is enabled, the solver builds a proof for {(=  ′)} at the same time it inductively
computes ′. The proof mainly uses the cong axiom for the induction step and a set of
solverspecific rewrite rules, such as (oracle +(= (ite t1 true t2) (or t1 t2)) :rewrite
iteBool3). These rewrite rules can later be easily replaced by their proof.</p>
      <p>In the second phase, the formula is split and converted to CNF. If the top-level formula is a
conjunction of smaller components, the formula is split into the components and the proof for
each component is tracked. The proofs are already generated in the final form, e.g., by resolving
the input formula with the and- axiom that corresponds to the component. If the formula is a
disjunction, the subproof is resolved with the or- axiom to split the formula into its literals. The
literals may be further rewritten into their internal form, which is again explained by rewrite
rules in form of oracles. These rewrite steps are integrated into the proof of the clause. Finally
the clause is added to the DPLL( ) engine and the clause keeps a reference to its proof. To
avoid exponential blow-up of the CNF transformation, a nested and term below a disjunction is
treated as a Boolean variable. A named literal is created and new clauses are created using the
Plaisted–Greenbaum algorithm. These new clauses are annotated with their proof, which is an
instance of the and- or and+ axiom.</p>
      <p>In the third phase, producing resolution proofs with the DPLL( ) algorithm is
straightforward. Theory lemmas are added by theory-specific decision procedures. These lemmas are
added as clauses to the DPLL( ) engine and are annotated with an oracle proof and explained
later when the final proof is computed.</p>
      <p>An earlier version of SMTInterpol used the rewrite rules and theory lemmas as its axioms
and implemented a proof checker that checked these solver-specific rules. However, we found
that writing a proof checker for custom rules leaves room for errors. Soundness errors in the
proof checker are never caught, as testing is usually only done with correct proofs. While it is
possible to write unit tests that specifically create invalid instances of proof rules, this is itself a
tedious task with no reward and was never done.</p>
      <p>Therefore, we created a proof translator that replaces each solver-specific oracle rule with a
corresponding proof using only the axioms. This gives much more confidence, as a wrong rule
cannot be explained by a valid proof. The proof translator from the solver-specific rules to the
minimal rules is roughly the same size as the old proof checker. The new proof checker only
has to handle the much simpler and smaller set of axioms and is less than a third the size of
the old proof checker. More importantly, with the new proof format the trusted core does not
have to be changed when new rewrite rules are added to the solver. Only the proof translator is
afected, which is producing a certificate of correctness.</p>
    </sec>
    <sec id="sec-6">
      <title>6. Proof Techniques</title>
      <p>Our proof format optimizes simplicity of the proof checker over simplicity of the prover.
Nonetheless, we think that the language is expressive enough to also allow for advanced proof
techniques that exponentially decrease the proof size. In this section we investigate this in
detail.</p>
      <p>These techniques are made possible by the expressiveness of SMT-LIB, which we use for
literals, and by having a complete set of axioms. Normally, resolution is only refutation-complete,
i.e., if  is valid, one can derive a contradiction from ¬. Our format can prove the unit clause
{} from the axioms if  is valid: The idea is to prove the clause {(!  :x), ¬} from the
axioms (del!  :x) and (=-1 (!  :x) p)). Using refutation completeness, a proof for
{(!  :x)} can be constructed, and then for {} using the axioms del! and =-2.
Logging Proofs is a technique where provers output their proofs on the fly into a file. The
main reason for doing this is to keep the memory overhead low. The proofs can be forgotten after
writing them to the proof file. Our proof format supports this technique using the let-proof
command. Instead of remembering the proof for every clause, one can directly write the line
(let-proof (( prf  ))
into the proof file, where  is a unique identifier for the clause and prf  the proof for this
clause. If  was proved by resolution from other clauses, prf  can use the identifiers of the
other clauses and combine them with the rule res. Deleted clauses can be indicated by assigning
a trivial clause, e.g., true+ to the previously used clause identifier.</p>
      <p>To avoid repeating shared subterms, they can also be assigned to an identifier using let
when they are first used. The prover just needs to give every subterm a unique identifier and
subsequently use this identifier to refer to the subterm. To ensure that the parentheses match,
the prover only needs to count the number of opening parentheses to add the same number of
closing parentheses at the end.</p>
      <p>
        Extended Resolution [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ] introduces a new literal that stands for the conjunction of two
existing literals together with corresponding clauses. This technique can be exponentially more
succinct than using plain resolution proofs [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] and it can simulate DRAT proofs [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]. Extended
resolution is already built into our proof format, since the conjunction of two literals can be
expressed as an SMT-LIB formula and the added clauses are just instances of the and+ and
andaxioms. Thus, an extended resolution proof can be expressed as follows.
(let ((p (and p1 p2))) (let-proof ((C1 (and+ p1 p2))
      </p>
      <p>(C2 (and- 0 p1 p2)) (C3 (and- 1 p1 p2))) ...))
Quantifier Introduction is usually done by a rule all-intro that takes a subproof prf  for
a formula  containing a free variable x and returns a proof for (forall ((x  )) ). In our
proof format, there is no such rule and also free variables are not allowed in proofs. Nonetheless
it is possible to express this rule using resolution, let binders and the forall+ axiom.</p>
      <p>
        (let ((x (choose (x  ) (not )))) (res  prf  (forall+ ((x  )) )))
Symmetry Breaking is a technique that can greatly reduce the search space by exploiting
symmetry [
        <xref ref-type="bibr" rid="ref5 ref6">5, 6</xref>
        ]. The idea is to detect symmetry with respect to certain input variables, i.e., find
a renaming of the constants such that the input formula is equivalent to itself after renaming. For
example, consider a formula  (1, 2) with two uninterpreted constants 1 and 2. Assume that
 is symmetric, i.e.,  (1, 2) is equivalent to  (2, 1), e.g., it difers only in the order of the
terms in commutative operators. If there is a clause (or (p 1) (p 2)) in this formula, then
w.l.o.g. one can assume that (p 1) holds: if adding (p 1) to  is unsatisfiable, it is clear by
symmetry that adding (p 2) to  is also unsatisfiable, hence  is unsatisfiable. Adding (p 1)
to  is called symmetry breaking, since after adding it, the formula is no longer symmetric
with respect to this renaming. The reason why this is sound is because if (p 1) does not hold,
then (p 2) holds. In this case we can swap 1 and 2 by defining ′1 := 2 and ′2 := 1. By
symmetry now  (′1, ′2) still holds and additionally (p ′1) holds.
      </p>
      <p>This can be formally expressed in our proof format. First define ′1 := (ite (p 1) 1 2)
and ′2 := (ite (p 1) 2 1). These definitions can be introduced using the let keyword.
Then show that  (1, 2) =  (′1, ′2) holds by case distinction over (p 1) and exploiting the
symmetry if (p 1) is false. Thus one can prove  ′ from  where  ′ is the formula containing
′1 and ′2. Now one can show from (or (p 1) (p 2)) that (p ′1) holds, again by case
distinction over (p 1). The remaining proof is now done on the renamed formula, using ′1
and ′2, ignoring their definition but treating them as uninterpreted constants.</p>
      <p>The proof for  =  ′ is linear in the size of  and for each of the two cases proceeds by
induction over  using ite1/ite2 for the leaves, and an instance of cong for every subterm.
Commutativity of logical operators needs to be explicitly proved. The proof of (p ′1) is simple
and requires ite1, ite2, congruence over p, and equivalence reasoning. An example proof
using this technique is provided with the online proof checker on our website.</p>
    </sec>
    <sec id="sec-7">
      <title>7. Related Work</title>
      <p>
        Böhme and Weber [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] published guidelines for proof formats. Proofs should be human-readable
(i.e., not in binary format), but easy to parse. They should include suficient detail for the proof
checker but avoid redundancy, e.g., clauses that were never used. The proof rules should be
simple and canonical, and avoid special cases. Proofs should explicitly contain the proved facts.
Our proof format follows these guidelines in most aspects. For the last point, our format allows
the prover to annotate each proof term with the clause it proves, but this is not mandatory.
      </p>
      <p>
        For SAT solvers a standardized proof format is DRAT [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]. A DRAT proof consists of a list of
clauses in such a way that each clause can be derived from the previous clauses by well-defined
rules. However, DRAT assumes that the input is already in CNF and there is no support for
theory lemmas needed in SMT. More importantly, the RAT property in each proof step must be
checked against all (not yet deleted) input clauses. This means all used theory lemmas must be
introduced in the beginning, otherwise the proof is unsound.
      </p>
      <p>
        CVC5 uses LFSC [
        <xref ref-type="bibr" rid="ref10 ref9">9, 10</xref>
        ] for its proofs. LFSC can be seen as a language for writing proof
checkers and provides a syntax for proof rules and a functional language for expressing
nonsyntactical side conditions. The rules and side conditions written in this language are part of
the trusted core of the proof checker. CVC5 uses about 100 rules for core theory and arithmetic
with about 40 subroutines to check side conditions. Some of the rules are similar to ours, e.g.,
they have a rule for resolution, where the resolvent is computed by the side condition. Overall,
they have more rules and some of them are specific to the way their solver works.
      </p>
      <p>
        Alethe4 [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ] is also based on resolution, but has a few rules following natural deduction
style. Facts are represented as clauses similar to us. In contrast to our format, they require
to give the proved clause for every intermediate step, but they allow for more complicated
reasoning like hyper-resolution to combine several resolutions into one proof step. The Alethe
specification mentions that the theoretical complexity of checking their resolution rule is
NPcomplete. Compared to our format, Alethe contains more rules and axioms. Alethe has a rule
for let expansion but expansion of defined function (and named terms) is automatic, which
is the opposite of what our format does. Our feeling is that automatic function expansion is
problematic, because substituting function arguments can lead to exponential blow-up in the
worst case. Also let enables us to express the forall- axiom syntactically.
      </p>
      <p>
        The proof format of OpenSMT [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ] is more a collection of proof formats. They use certificates
to explain CNF conversion using Tseitin and De Morgan rules. The theory lemmas are explained
by certificates in a theory-specific format. Each certificate is specific to the rules used by the
solver, and so is the certificate checker. The remaining proof is purely propositional and uses
the DRAT format.
      </p>
      <p>Quip5 is an experimental proof format for first-order and higher-order logic. It aims at proofs
that are easy to produce by providing high-level proof rules and redundant rules (e.g. resolution
and unit resolution). In return, the proof checker needs to perform more complex reasoning, e.g.
congruence closure and other theory-specific reasoning. The format is resolution-based and
also uses clauses with SMT-LIB formulas, but it also supports hyperresolution steps. Shared
terms are abbreviated by the top-level command deft, which corresponds to let in our format.</p>
      <p>
        The Z3 proof format [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ] is based on natural deduction. Interestingly, it does not have a
generic resolution rule. Instead it has a lemma rule for RUP steps that adds all literals negated
as hypothesis and then only uses unit resolution on these hypotheses and existing clauses.
The format uses mainly proof rules, e.g. for symmetry, transitivity, and congruence, using the
hypothesis rule for decided literals that end up negated in the proved clause. For input formulas
4Specification available at https://verit.loria.fr/documentation/alethe-spec.pdf
5See https://github.com/c-cube/quip and https://c-cube.github.io/quip-book
it uses a rewrite rule whose side condition is that the rewritten term is equal to the original
(they are similar to our oracle axioms in that they are not proved). For NNF encoding they use
quoted formulas, which means they use SMT-LIB formulas as literals like we do. The paper
does not mention how let-terms are handled, but the proof format uses them in the same way
as our format and, like our let-proof, to abbreviate common subproofs. Proofs are SMT-LIB
terms of sort Proof.
      </p>
    </sec>
    <sec id="sec-8">
      <title>8. Conclusion and Discussion</title>
      <p>We presented a simple proof format for SMT based on the resolution rule. Its main feature
is its restriction to only a few basic axioms. In total we currently define one rule (resolution)
and 60 axioms for the core theory, arithmetic, arrays, and datatypes, which is on average two
axioms per theory-defined function. By implementing this proof format in our SMT solver, we
have shown that despite its simplicity, the format can succinctly express the reasoning steps
done by our solver. We have also shown that the format can handle more advanced reasoning
techniques like symmetry breaking.</p>
      <p>Every single proof format may favour some solvers while making it more dificult for other
solvers to express their proofs. Our format is based on the resolution rule, which favours solvers
based on DPLL( ). Moreover, the axioms for linear arithmetic, especially the axiom farkas,
are inspired by the theory lemmas that our solver produces. However, other proof formats like
CVC5’s LFSC, Alethe, and Quip are also based on resolution and Alethe has a rule la_generic
that is almost identical to farkas. In fact, most of our axioms are also contained in Alethe in
the same or a similar form. Our experience with SMTInterpol gives us confidence that proofs
from SMT solvers can be translated into this format with moderate overhead.</p>
      <p>In our format, rules with assumptions are expressed as axioms, e.g., modus ponens is expressed
as =&gt;- where the premises are negated literals and the conclusion a positive literal. The axiom
form is more flexible, e.g., introduction rules can also be used to eliminate negated operators.
Also the axioms are needed in this form to explain the Tseitin encoding.</p>
      <p>The main reason we do not use the SMT-LIB operators or/not to represent clauses or negated
literals is to make a clean separation between the meta-language (resolution proofs) and the
language in which the formulas are written. This avoids ambiguity, whether a term (or 1 2)
represents a Tseitin literal or a clause. It also avoids problems with double negation; other proof
formats interpret terms starting with not as negated literal but double negated literals are seen
as positive. Note that the only place we use a concrete syntax for clauses is the oracle rule.</p>
      <p>Implicitly expanding let terms seems to go against the goal of a low-level proof format,
but this is essential. First, a way of defining names for repeatedly used terms or clauses is
needed to avoid exponential blow-up. Second, our solver and proof checker represent formulas
and proofs internally using directed acyclic graphs (DAGs). In a way, let is just a concrete
syntax to represent DAGs in textual form. Finally, let is the SMT-LIB syntax for substituting
variables with terms, which is used in the quantifier elimination and introduction axioms and
the expand axiom for function definitions. Thus, we also use it to avoid inventing a new syntax
for substitutions.</p>
    </sec>
    <sec id="sec-9">
      <title>Acknowledgments</title>
      <p>This work is supported by the German Research Council (DFG) under HO 5606/1-2.</p>
    </sec>
    <sec id="sec-10">
      <title>A. Axioms of the Core Theory</title>
      <p>Axioms for the logical operators:</p>
      <p>true+ : {true}
false- : {¬false}
(not+ 0) : {(not 0), 0}
(not- 0) : {¬(not 0), ¬0}
(and+ 0 . . . ) : {(and 0 . . . ), ¬0, . . . , ¬}
(and-  0 . . . ) : {¬(and 0 . . . ), }
(or+  0 . . . ) : {(or 0 . . . ), ¬}
(=&gt;+  0 . . . ) : {(=&gt; 0 . . . ), (¬) }
(=&gt;- 0 . . . ) : {¬(=&gt; 0 . . . ), ¬0, . . . , }
(=+1 0 1) : {(= 0 1), 0, 1}
(=-1 0 1) : {¬(= 0 1), 0, ¬1}
(=+2 0 1) : {(= 0 1), ¬0, ¬1}
(=-2 0 1) : {¬(= 0 1), ¬0, 1}
(xor+ (1) (2) (3)) : {(xor 1), (xor 2), ¬(xor 3)}
(xor- (1) (2) (3)) : {¬(xor 1), ¬(xor 2), ¬(xor 3)}
where 1,2,3 are lists of terms with each term occurring an even number in total
and if  is only one term, (xor ) stands for the term .</p>
      <p>Axioms for quantifiers:
(forall+ ((1  1) . . . (  )) ) :
{(forall ((1  1) . . . (  )) ),
¬(let ((1 (choose (1  1) (forall ((2  2) . . . (  )) (not )))))
(let ((2 (choose (2  2) (forall ((3  3) . . . (  )) (not )))))
.
.
.</p>
      <p>(let (( (choose (  ) (not )))) )· · · ))}
(forall- ((1 1) . . . ( )) ) :</p>
      <p>{¬(forall ((1  1) . . . (  )) ), (let ((1 1). . .( )) )}
(exists+ ((1 1) . . . ( )) ) :</p>
      <p>{(exists ((1  1) . . . (  )) ), ¬(let ((1 1). . .( )) )}
(exists- ((1  1) . . . (  )) ) :
{¬(exists ((1  1) . . . (  )) ),
(let ((1 (choose (1  1) (exists ((2  2) . . . (  )) ))))
(let ((2 (choose (2  2) (exists ((3  3) . . . (  )) ))))
.
.
.
(let (( (choose (  ) ))) )· · · ))}
In the axioms forall- and exists+ the sorts   are automatically determined from the type
of the expressions .</p>
      <p>Axioms for equality:</p>
      <p>(refl ) : {(=  )}
(symm 0 1) : {(= 0 1), ¬(= 1 0)}
(trans 0 . . . ) : {(= 0 ), ¬(= 0 1), . . . , ¬(= − 1 )}
(cong (f 0 . . . ) (f ′0 . . . ′)):</p>
      <p>{(= (f 0 . . . ) (f ′0 . . . ′)), ¬(= 0 ′0), . . . , ¬(=  ′)}
(=+ 0 . . . ) : {(= 0 . . . ), ¬(= 0 1), . . . , ¬(= − 1 )}
(=-   0 . . . ) : {¬(= 0 . . . ), (=  )} where  ̸= 
(distinct+ 0 . . . ) : {(distinct 0 . . . ), (= 0 1), . . . , (= 0 ), . . . , (= − 1 )}
(distinct-   0 . . . ) : {¬(distinct 0 . . . ), ¬(=  )} where  ̸=</p>
      <sec id="sec-10-1">
        <title>Axioms for ite, annotations and define-fun:</title>
        <p>(ite1 0 1 2) : {(= (ite 0 1 2) 1), ¬0}
(ite2 0 1 2) : {(= (ite 0 1 2) 2), 0}</p>
        <p>(del!  . . .) : {(= (!  . . .) )}
(expand (f 0 . . . )) : {(= (f 0 . . . ) (let ((0 0). . .( )) ))}
where f is defined by (define-fun f ((0  0)...(  )) )</p>
      </sec>
      <sec id="sec-10-2">
        <title>Here are two examples for the xor axioms:</title>
        <p>(xor+ (1 2 3) (2) (1 3)) :{(xor 1 2 3), 2, ¬(xor 1 3)}
(xor- ( ) ( ) ( )) :{¬(xor  )}
B. Axioms of Linear Arithmetic
(poly+ (+ 1 . . . ) ) : {(= (+ 1 . . . ) )}
(poly* (* 1 . . . ) ) : {(= (* 1 . . . ) )}
where  = 1 + · · · + 
where  = 1 · · · 
(farkas 1 (&lt;=? 1 1′) . . .  (&lt;=?  ′)) : {¬(&lt;=? 1 1′), . . . , ¬(&lt;=?  ′)}
where  are positive integer constants, the weighted sum 1(1 − 1′) + · · · + ( − ′) is a
non-negative constant. &lt;=? stands for &lt;, &lt;=, or =, and if the weighted sum is zero, at least one
of the literals must be &lt;.</p>
        <p>(trichotomy 1 2) : {(&lt; 1 2), (= 1 2), (&lt; 2 1)}</p>
        <p>(total 1 2) : {(&lt;= 1 2), (&lt; 2 1)}
(total-int 1 ) : {(&lt;= 1 ), (&lt;=  + 1 1)}
where 1 has type Int,  is an integer constant in canonical form
and  + 1 the same integer constant increased by one in canonical form.
(to_real ) : {(= (to_real ) ′)}</p>
        <p>where ′ is the result of casting the integer polynomial  to real.</p>
        <p>(&gt;def 1 2) : {(= (&gt; 1 2) (&lt; 2 1))}
(&gt;=def 1 2) : {(= (&gt;= 1 2) (&lt;= 2 1))}
(/def 1 2 . . . ) : {(= 1 (* 2 . . .  (/ 1 2 . . . ))), (= 2 0), . . . , (=  0)}
(-def 1) : {(= (- 1) (* (- 1) 1))}
(-def 1 2 . . . ) : {(= (- 1 2 . . . ) (+ 1 (* (- 1) 2)) . . . (* (- 1) ))}
(to_int-low 1) : {(&lt;= (to_real (to_int 1)) 1)}
(to_int-high 1) : {(&lt; 1 (+ (to_real (to_int 1)) 1.0))}</p>
        <p>(abs-def 1) : {(= (abs 1) (ite (&lt; 1 0) (- 1) 1))}
(div-low 1 2) : {(&lt;= (* 2 (div 1 2)) 1), (= 2 0)}
(div-high 1 2) : {(&lt; 1 (+ (* 2 (div 1 2)) (abs 2))), (= 2 0)}
(mod-def 1 2) : {(= (mod 1 2) (- 1 (* 2 (div 1 2)))), (= 2 0)}
(divisible-def c 1) : {(= ((_ divisible c) 1) (= 1 (* c (div 1 c))))}</p>
      </sec>
    </sec>
    <sec id="sec-11">
      <title>C. Axioms of Arrays</title>
      <p>We support an extension of the array theory with @diff for returning the elements where two
arrays difer and @const for the array that stores the same element for all indices. In these
axioms  stands for a term of array type,  for a term of index type and  for a term of element
type.</p>
      <p>(selectstore1   ) :{(= (select (store   ) ) )}
(selectstore2  1 2 ) :{(= (select (store  1 ) 2) (select  2)), (= 1 2)}
(extdiff 0 1) :{(= 0 1), ¬(= (select 0 (@diff 0 1))</p>
      <p>(select 1 (@diff 0 1)))}
(const  ) :{(= (select (@const ) ) )}</p>
    </sec>
    <sec id="sec-12">
      <title>D. Axioms of Data Types</title>
      <p>In the following axioms, 1 . . . ,  are the constructors 1, . . .  are the selectors of .
(dt_project  1 . . . ) :{(= ( ( 1 . . . )) )}</p>
      <p>(dt_cons  ) :{¬((_ is ) ), (= ( (1 ). . . ( )) )}
(dt_test+  ( 1 . . . )) :{((_ is ) ( 1 . . . ))}
(dt_test-  ( 1 . . . )) :{¬((_ is ) ( 1 . . . ))} where  ̸= 
(dt_exhaust ) :{((_ is 1) ), . . . , ((_ is ) )}
(dt_match (match  . . . )) :{(= (match t (( 1 . . . ) ) . . . )
(ite ((_ is ) t)
(let ((1 (1 )). . . ( ( ))) ) . . . )}</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>C.</given-names>
            <surname>Barrett</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Fontaine</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Tinelli</surname>
          </string-name>
          ,
          <source>The SMT-LIB Standard: Version 2</source>
          .6,
          <string-name>
            <surname>Technical</surname>
            <given-names>Report</given-names>
          </string-name>
          , Department of Computer Science, The University of Iowa,
          <year>2017</year>
          . Available at www.
          <source>SMT-LIB.org.</source>
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>G. S.</given-names>
            <surname>Tseitin</surname>
          </string-name>
          ,
          <article-title>On the complexity of derivation in propositional calculus</article-title>
          ,
          <source>in: Automation of Reasoning: 2: Classical Papers on Computational Logic</source>
          <year>1967</year>
          -1970, Springer,
          <year>1983</year>
          , pp.
          <fpage>466</fpage>
          -
          <lpage>483</lpage>
          . URL: https://doi.org/10.1007/978-3-
          <fpage>642</fpage>
          -81955-1_
          <fpage>28</fpage>
          . doi:
          <volume>10</volume>
          .1007/ 978-3-
          <fpage>642</fpage>
          -81955-1_
          <fpage>28</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>S. A.</given-names>
            <surname>Cook</surname>
          </string-name>
          ,
          <article-title>A short proof of the pigeon hole principle using extended resolution</article-title>
          ,
          <source>SIGACT News 8</source>
          (
          <year>1976</year>
          )
          <fpage>28</fpage>
          -
          <lpage>32</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>B.</given-names>
            <surname>Kiesl</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Rebola-Pardo</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. J. H.</given-names>
            <surname>Heule</surname>
          </string-name>
          ,
          <article-title>Extended resolution simulates DRAT</article-title>
          , in: IJCAR, volume
          <volume>10900</volume>
          of Lecture Notes in Computer Science, Springer,
          <year>2018</year>
          , pp.
          <fpage>516</fpage>
          -
          <lpage>531</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>H.</given-names>
            <surname>Katebi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K. A.</given-names>
            <surname>Sakallah</surname>
          </string-name>
          ,
          <string-name>
            <given-names>I. L.</given-names>
            <surname>Markov</surname>
          </string-name>
          ,
          <article-title>Symmetry and satisfiability: An update</article-title>
          ,
          <source>in: SAT</source>
          , volume
          <volume>6175</volume>
          of Lecture Notes in Computer Science, Springer,
          <year>2010</year>
          , pp.
          <fpage>113</fpage>
          -
          <lpage>127</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>D.</given-names>
            <surname>Déharbe</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Fontaine</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Merz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B. W.</given-names>
            <surname>Paleo</surname>
          </string-name>
          ,
          <article-title>Exploiting symmetry in SMT problems</article-title>
          , in: CADE, volume
          <volume>6803</volume>
          of Lecture Notes in Computer Science, Springer,
          <year>2011</year>
          , pp.
          <fpage>222</fpage>
          -
          <lpage>236</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>S.</given-names>
            <surname>Böhme</surname>
          </string-name>
          , T. Weber,
          <article-title>Designing proof formats: A user's perspective</article-title>
          , in: PxTP,
          <year>2011</year>
          , pp.
          <fpage>27</fpage>
          -
          <lpage>32</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>M. J. H.</given-names>
            <surname>Heule</surname>
          </string-name>
          ,
          <article-title>The DRAT format and DRAT-trim checker</article-title>
          ,
          <source>CoRR abs/1610</source>
          .06229 (
          <year>2016</year>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>A.</given-names>
            <surname>Stump</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Oe</surname>
          </string-name>
          ,
          <article-title>Towards an SMT proof format</article-title>
          , in: SMT '08/BPR '08,
          <string-name>
            <surname>ACM</surname>
          </string-name>
          ,
          <year>2008</year>
          , p.
          <fpage>27</fpage>
          -
          <lpage>32</lpage>
          . URL: https://doi.org/10.1145/1512464.1512470. doi:
          <volume>10</volume>
          .1145/1512464.1512470.
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>A.</given-names>
            <surname>Stump</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Oe</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Reynolds</surname>
          </string-name>
          ,
          <string-name>
            <given-names>L.</given-names>
            <surname>Hadarean</surname>
          </string-name>
          ,
          <string-name>
            <surname>C.</surname>
          </string-name>
          <article-title>Tinelli, SMT proof checking using a logical framework</article-title>
          ,
          <source>Formal Methods Syst. Des</source>
          .
          <volume>42</volume>
          (
          <year>2013</year>
          )
          <fpage>91</fpage>
          -
          <lpage>118</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>H.</given-names>
            <surname>Schurr</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Fleury</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Barbosa</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Fontaine</surname>
          </string-name>
          , Alethe:
          <article-title>Towards a generic SMT proof format (extended abstract)</article-title>
          ,
          <source>in: PxTP</source>
          , volume
          <volume>336</volume>
          <source>of EPTCS</source>
          ,
          <year>2021</year>
          , pp.
          <fpage>49</fpage>
          -
          <lpage>54</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>R.</given-names>
            <surname>Otoni</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Blicha</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Eugster</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. E. J.</given-names>
            <surname>Hyvärinen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Sharygina</surname>
          </string-name>
          ,
          <article-title>Theory-specific proof steps witnessing correctness of SMT executions</article-title>
          , in: DAC, IEEE,
          <year>2021</year>
          , pp.
          <fpage>541</fpage>
          -
          <lpage>546</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <surname>L. M. de Moura</surname>
          </string-name>
          , N. Bjørner,
          <article-title>Proofs and refutations, and Z3</article-title>
          , in: LPAR Workshops, volume
          <volume>418</volume>
          <source>of CEUR Workshop Proceedings, CEUR-WS.org</source>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          <article-title>(dt_acyclic 0 (1</article-title>
          . . . )) :{¬(= 0 )} where  ≥ 1,  is the -th argument of − 1 and
          <article-title>− 1 is an application of a constructor for  = 1, .</article-title>
          . . , . Hence,
          <article-title>appears nested inside the constructor term 0.</article-title>
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>