<!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 />
    <article-meta>
      <title-group>
        <article-title>Tautology Checkers in Isabelle and Haskell ?</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Prover.hs</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Algorithms, Logic and Graphs Section Department of Applied Mathematics and Computer Science Technical University of Denmark Richard Petersens Plads</institution>
          ,
          <addr-line>Building 324, DK-2800 Kongens Lyngby</addr-line>
          ,
          <country country="DK">Denmark</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>With the purpose of teaching functional programming and automated reasoning to computer science students, we formally verify a sound, complete and terminating tautology checker in Isabelle with code generation to Haskell. We describe a series of approaches and nish with a formalization based on formulas in negation normal form where the Isabelle/HOL functions consist of just 4 lines and the Isabelle/HOL proofs also consist of just 4 lines. We investigate the generated Haskell code and present a 24-line manually assembled program.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <p>Logic textbooks usually have pen-and-paper proofs only. But we nd that the
formalization of logic can be a very rewarding endeavor.</p>
      <sec id="sec-1-1">
        <title>Our main interest in the formalizations of logic is for teaching an advanced</title>
        <p>
          course on automated reasoning for computer science students at the Technical
University of Denmark (DTU). The prerequisites for the automated reasoning
course include courses in logic and functional programming. In the course, we
start with the formal veri cation of a sound, complete and terminating tautology
checker as described in the present paper. We end with the formal veri cation
of a proof system kernel for rst-order logic [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ].
        </p>
      </sec>
      <sec id="sec-1-2">
        <title>Both in our courses and and in our student projects and theses we mainly use the proof assistant Isabelle/HOL [10].</title>
        <p>https://isabelle.in.tum.de/</p>
      </sec>
      <sec id="sec-1-3">
        <title>The Isabelle formalizations are available here:</title>
      </sec>
      <sec id="sec-1-4">
        <title>The main formalization is in the le Prover.thy and the whole tautology checker | with Isabelle proofs of soundness, completeness and termination as well as a small example and the code generation to Haskell | even ts on a single slide (25 lines including blank lines).</title>
        <p>We present a small Isabelle code generation example in Section 2. We discuss
related work in Section 3. In Section 4 we investigate a tautology checker based on
the standard two-sided sequent calculus with falsity and implication. In Section 5
we investigate tautology checkers based on a one-sided sequent calculus with
negation and conjunction and also with negation and disjunction. In Section 6
we describe in details a formalization of a tautology checker based on a
onesided sequent calculus with formulas in negation normal form (NNF). Finally,
we conclude with future work in Section 7.
2</p>
      </sec>
    </sec>
    <sec id="sec-2">
      <title>Code Generation in Isabelle</title>
      <sec id="sec-2-1">
        <title>Consider the following example from the Isabelle manual on code generation:</title>
      </sec>
      <sec id="sec-2-2">
        <title>The example provides functions for amortized queues by keeping two lists</title>
        <p>and performing a list reversal when necessary. We often leave out the types but
for the constant `empty' the type is needed since there is already a constant
empty for the set ; imported from the theory Main.</p>
      </sec>
      <sec id="sec-2-3">
        <title>We have extended the example in the manual with a theorem and a proof:</title>
        <p>unfolding empty def by simp (which rst unfolds the de nition of the empty
queue and then nishes the proof by simpli cation of the resulting expression).</p>
      </sec>
      <sec id="sec-2-4">
        <title>The screenshot shows two `Info' pop-up windows to the right. The top one reports that termination for the enqueue/dequeue functions have been automatically proved and the bottom one reports that the code generation to Haskell has been successful.</title>
        <p>The exported lines are essentially as follows:
import Prelude (Maybe(..), print, reverse)
data Queue a = AQueue [a] [a]
empty = AQueue [] []
enqueue x (AQueue xs ys) = AQueue (x : xs) ys
dequeue (AQueue [] []) = (Nothing, AQueue [] [])
dequeue (AQueue xs (y : ys)) = (Just y, AQueue xs ys)
dequeue (AQueue (x : xs) []) =</p>
        <p>(case reverse (x : xs) of y : ys -&gt; (Just y, AQueue [] ys))
main = print (case dequeue (enqueue 0 empty) of (Just x, _) -&gt; x)</p>
      </sec>
      <sec id="sec-2-5">
        <title>Isabelle can generate code to Haskell, OCaml, Scala and Standard ML. Note that the Isabelle theorem establishes a fact for all n (of any type) but the Haskell printout only concerns the value 0.</title>
        <p>3</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Related Work</title>
      <p>
        Completeness proofs go back to Hilbert for propositional logic [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] and to Godel
for rst-order logic [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ]. Henkin simpli ed Godel's proof [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ].
      </p>
      <sec id="sec-3-1">
        <title>Shankar [13] formalized in 1985 a tautology checker for propositional logic using the Boyer-Moore theorem prover.</title>
      </sec>
      <sec id="sec-3-2">
        <title>Michaelis and Nipkow recently formalized propositional proof systems in</title>
        <p>
          Isabelle/HOL [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ]. We have used their formalization as starting point but we
avoid the use of a prover returning counterexamples. We have also made the
prover non-sequential, i.e. deterministic, and have simpli ed the termination
measure as well as the soundness and completeness proofs.
        </p>
      </sec>
      <sec id="sec-3-3">
        <title>Nowadays many provers for propositional logic are based on SAT solving and the resolution calculus [1]. Systems like leanTAP for rst-order logic are usually not formally veri ed [3]. Schlichtkrull has proved the completeness of rst-order resolution, also in Isabelle/HOL [12].</title>
      </sec>
      <sec id="sec-3-4">
        <title>Blanchette gives an overview of the formalized metatheory of various other logical calculi and automatic provers in Isabelle/HOL [2]. Paulson formalized Godel's incompleteness theorems in Isabelle/HOL [11]. Kumar et al. formalized higher-order logic [8] (soundness only).</title>
      </sec>
      <sec id="sec-3-5">
        <title>For our introductory course on logical systems and logic programming we have recently developed the Sequent Calculus Veri er (SeCaV) for rst-order logic [4] but it consists of thousands of lines in Isabelle/HOL and has no decision procedure.</title>
      </sec>
      <sec id="sec-3-6">
        <title>We recently gave a talk \A Micro Prover for Teaching Automated Reasoning"</title>
        <p>(presentation only) at the Seventh Workshop on Practical Aspects of Automated</p>
      </sec>
      <sec id="sec-3-7">
        <title>Reasoning (PAAR 2020).</title>
        <p>Sequent Calculus | Falsity and Implication
We rst investigate a tautology checker based on the standard two-sided sequent
calculus with falsity and implication.</p>
      </sec>
      <sec id="sec-3-8">
        <title>Formulas p, q, . . . in classical propositional logic are built from propositional</title>
        <p>variables (not further speci ed for now), falsity (?) and implications (p ! q).</p>
      </sec>
      <sec id="sec-3-9">
        <title>Let and be nite sets of formulas.</title>
      </sec>
      <sec id="sec-3-10">
        <title>The axioms of the sequent calculus are of the form:</title>
        <p>[ fpg `
[ fpg
[ fpg [ fqg `
[ fp ! qg `
[ fpg ` [ fqg
` [ fp ! qg</p>
        <p>We obtain the following Haskell code (we often use our own list membership
function in order to make it a bit easier to consider various other functional
programming languages):
import Prelude ((&amp;&amp;), (||), (==), Bool(..), print)
data Form a = Pro a | Falsity | Imp (Form a) (Form a)
member _ [] = False
member m (n : a) = m == n || member m a
common _ [] = False
common a (m : b) = member m a || common a b
mp a b (Pro n : c) [] = mp (n : a) b c []
mp a b c (Pro n : d) = mp a (n : b) c d
mp _ _ (Falsity : _) [] = True
mp a b c (Falsity : d) = mp a b c d
mp a b (Imp p q : c) [] = mp a b c [p] &amp;&amp; mp a b (q : c) []
mp a b c (Imp p q : d) = mp a b (p : c) (q : d)
mp a b [] [] = common a b
prover p = mp [] [] [] [p]
main = print (prover (Imp (Pro 0) (Pro 0)))</p>
      </sec>
      <sec id="sec-3-11">
        <title>We leave the underlying sequent calculus implicit. The last two arguments are the two sides of a sequent. The rst two arguments are lists of propositional variables that we have so far encountered in the left side and in the right side, respectively, as made clear in the two rst cases of the function.</title>
      </sec>
      <sec id="sec-3-12">
        <title>The formalization is in the following le:</title>
        <sec id="sec-3-12-1">
          <title>Implication.thy</title>
        </sec>
      </sec>
      <sec id="sec-3-13">
        <title>Unfortunately the Isabelle formalization is almost a hundred lines. We obtain a much smaller formalization by simplifying the sequent calculus, as we describe in the rest of the paper.</title>
        <p>5 Conjunction, Disjunction and Negation
Before we consider formulas in negation normal form (NNF) we rst investigate
a tautology checker based on a one-sided sequent calculus with negation and
conjunction.
import Prelude ((&amp;&amp;), (||), (==), Bool(..), print)
data Form a = Pro a | Neg (Form a) | Con (Form a) (Form a)
member _ [] = False
member m (n : a) = m == n || member m a
common _ [] = False
common a (m : b) = member m a || common a b
mp a b (Pro n : c) = mp (n : a) b c
mp a b (Neg (Pro n) : c) = mp a (n : b) c
mp a b (Neg (Neg p) : c) = mp a b (p : c)
mp a b (Neg (Con p q) : c) = mp a b (Neg p : Neg q : c)
mp a b (Con p q : c) = mp a b (p : c) &amp;&amp; mp a b (q : c)
mp a b [] = common a b
sz (Pro _) = 1
sz (Neg p) = 1 + sz p
sz (Con p q) = 2 + sz p + sz q</p>
      </sec>
      <sec id="sec-3-14">
        <title>But except for the complication concerning the termination proof the above tautology checker is straightforward. We then investigate a tautology checker based on a one-sided sequent calculus with negation and disjunction.</title>
      </sec>
      <sec id="sec-3-15">
        <title>The termination proof does not require any special size function and the above tautology checker is straightforward.</title>
      </sec>
      <sec id="sec-3-16">
        <title>The formalizations are in the following les:</title>
        <sec id="sec-3-16-1">
          <title>Conjunction.thy</title>
        </sec>
        <sec id="sec-3-16-2">
          <title>Disjunction.thy</title>
        </sec>
      </sec>
      <sec id="sec-3-17">
        <title>The formalizations are in all cases almost a hundred lines and so we turn to a tautology checker based on a one-sided sequent calculus with formulas in negation normal form (NNF).</title>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Negation Normal Form</title>
      <p>We describe a concise formalization of a tautology checker based on a one-sided
sequent calculus with formulas in negation normal form (NNF).</p>
      <sec id="sec-4-1">
        <title>In the micro prover we use sets of propositional variables instead of lists of</title>
        <p>propositional variables. This makes the formalization in Isabelle a bit shorter
but in general makes the generated code in Haskell longer.</p>
        <p>We start by showing the entire formalization and then we describe the
formalization in details. The formalization has the usual boilerplate, like the rst
line with the name of the theory and the last line with the end command:
theory Prover imports Main begin
datatype 0a form = Atom bool 0a j Op h 0a form i bool h 0a form i
primrec val where
h val i (Atom b n) = (if b then i n else : i n) i j
h val i (Op p b q) = (if b then val i p ^ val i q else val i p _ val i q) i
value h prover (Op (Atom True n) False (Atom False n)) i
theorem h prover p ! (8 i : val i p) i</p>
        <p>unfolding complete prover-def by auto
end</p>
        <p>
          Isabelle/HOL has a special intelligible semi-automated reasoning language,
Isar for short [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ], in which we normally formulate our proofs, but the classical
reasoner (auto) of Isabelle/HOL [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ] is so powerful that by de ning the lemmas
just right there is hardly any proving left for us to do.
        </p>
        <p>We now describe the formalization in details. Formulas in negation normal
form (NNF) are obtained using the following equivalences:
!</p>
        <p>: _
:( ^ )
(: _ : )
$</p>
        <p>( ! ) ^ (
:( _ )
(: ^ : )</p>
        <p>! )
::</p>
      </sec>
      <sec id="sec-4-2">
        <title>So we are left with atomic propositional formulas, possibly negated, and build propositional formulas using conjunction and disjunction.</title>
        <p>datatype 0a form = Atom bool 0a j Op h 0a form i bool h 0a form i</p>
      </sec>
      <sec id="sec-4-3">
        <title>We use a boolean to indicate a negated atomic propositional formula and we use a boolean to choose between conjunction and disjunction. This is re ected in the semantics, the function val, taking a formula and an interpretation (i).</title>
        <p>primrec val where
h val i (Atom b n) = (if b then i n else : i n) i j
h val i (Op p b q) = (if b then val i p ^ val i q else val i p _ val i q) i</p>
        <p>The type of the interpretation (i) is automatically inferred.</p>
      </sec>
      <sec id="sec-4-4">
        <title>The micro prover, the function cal, is a combination of the previously de ned</title>
        <p>provers based on conjunction, disjunction and negation.</p>
      </sec>
      <sec id="sec-4-5">
        <title>A function de nition produces a proof obligation which expresses complete</title>
        <p>ness and compatibility of patterns that is usually solved by a combination of the
methods pat completeness and auto (simpli cation of all goals).</p>
      </sec>
      <sec id="sec-4-6">
        <title>Termination of the function cal must be proved. The termination proof also</title>
        <p>uses the method auto with a sum of the formula sizes as the decreasing measure.</p>
      </sec>
      <sec id="sec-4-7">
        <title>We now obtain the tautology checker using a simple de nition (it is not possible to use an abbreviation instead when we want to use code generation).</title>
        <p>de nition h prover p
cal (fg; fg) [p] i</p>
      </sec>
      <sec id="sec-4-8">
        <title>After the termination proof we can execute the tautology checker and move on to the proof of soundness and completeness.</title>
        <p>value h prover (Op (Atom True n) False (Atom False n)) i</p>
      </sec>
      <sec id="sec-4-9">
        <title>The above command uses normalization by evaluation (NBE) and compiles</title>
        <p>the expression to Standard ML and executes it as such using the integration of</p>
      </sec>
      <sec id="sec-4-10">
        <title>Standard ML in Isabelle/HOL.</title>
        <p>lemma complete: h cal e s !</p>
        <p>(8 i : 9 p 2 set s [ Atom True ` fst e [ Atom False ` snd e: val i p) i
unfolding bex-Un by (induct rule: cal :induct ) (auto split : if-split )</p>
      </sec>
      <sec id="sec-4-11">
        <title>This is the key lemma for the soundness and completeness proof.</title>
        <p>Some comments:
{ We need to state the lemma for arbitrary arguments e and s in order for the
induction proof to go through.
{ We formulate the validity of the sequent in the usual way by requiring that
for all interpretations i there exists a formula p where the semantics is true.
{ We use the function set to turn the list into a set of formulas because the
proof automation for set theory is very strong.</p>
        <p>{ We nally solve all proof obligations using the method auto.
theorem h prover p ! (8 i : val i p) i
unfolding complete prover-def by auto</p>
      </sec>
      <sec id="sec-4-12">
        <title>This is the soundness and completeness proof based on the lemma complete and the de nition of the prover prover.</title>
        <p>export-code prover in Haskell</p>
      </sec>
      <sec id="sec-4-13">
        <title>We export the code to Haskell. In order to allow for experiments we export the tautology checker prover. The function cal is added automatically. The result of the code generation can be found in the Appendix. We present the following 24-line manually assembled program based on the code generation.</title>
        <p>import Prelude ((&amp;&amp;), (||), (==), Bool(..), print)
fst (x, _) = x
snd (_, y) = y
any _ [] = False
any p (x : xs) = p x || any p xs
fold f (x : xs) s = fold f xs (f x s)
fold _ [] s = s
member [] _ = False
member (x : xs) y = x == y || member xs y
newtype Set a = Set [a]
bex_set (Set xs) p = any p xs
bot_set = Set []
insert_set x (Set xs) = Set (if member xs x then xs else x : xs)
member_set x (Set xs) = member xs x
sup_set (Set xs) a = fold insert_set xs a
data Form a = Atom Bool a | Op (Form a) Bool (Form a)
cal e [] = bex_set (fst e) (\ n -&gt; member_set n (snd e))
cal e (Atom b n : s) =
(if b then cal (sup_set (insert_set n bot_set) (fst e), snd e) s
else cal (fst e, sup_set (snd e) (insert_set n bot_set)) s)
cal e (Op p b q : s) =</p>
        <p>(if b then cal e (p : s) &amp;&amp; cal e (q : s) else cal e (p : q : s))
prover p = cal (bot_set, bot_set) [p]
main = print (prover (Op (Atom True 0) False (Atom False 0)))</p>
      </sec>
      <sec id="sec-4-14">
        <title>Of course it is better to use the result of the code generation without modi cation but it is nevertheless relevant for teaching purposes that a simple program can easily be manually assembled.</title>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>Conclusion and Future Work</title>
      <p>We have presented a formalization of a tautology checker for propositional logic
with termination, soundness and completeness proofs in Isabelle/HOL. We can
use the code export features of Isabelle/HOL to generate standalone Haskell,
OCaml, Scala or Standard ML code. The formalized provers are for small, but
adequate, fragments of classical propositional logic.</p>
      <sec id="sec-5-1">
        <title>The automation in Isabelle/HOL is very powerful. In particular the function package is powerful and easy to use. The termination proof is independent of the function speci cation but supplying a termination proof makes an induction principle and code generation available.</title>
      </sec>
      <sec id="sec-5-2">
        <title>The micro provers are simple but not trivial: they break down the formula in</title>
        <p>the style of a sequent calculus and not even termination is veri ed automatically.
The micro provers are concise enough to be the rst examples in a course on
automated reasoning. Our approach shows how to use Isabelle/HOL and it also
shows a prover program in Haskell with termination, soundness and completeness
proofs.</p>
      </sec>
      <sec id="sec-5-3">
        <title>We are working on formalizations of micro provers in other proof assistants like Agda and Coq. We also plan to consider provers for rst-order logic and higher-order logic.</title>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>Acknowledgements</title>
      <p>Thanks to Asta Halkj r From, Alexander Birch Jensen and Anders Schlichtkrull
for discussions.</p>
    </sec>
    <sec id="sec-7">
      <title>Appendix: Isabelle Code Generation</title>
      <p>Listing of the three Haskell les exported from the Isabelle theory le Prover.thy
List.hs
{-# LANGUAGE EmptyDataDecls, RankNTypes, ScopedTypeVariables #-}
module List(fold, member, insert, removeAll) where {
import Prelude ((==), (/=), (&lt;), (&lt;=), (&gt;=), (&gt;), (+), (-), (*), (/), (**),
(&gt;&gt;=), (&gt;&gt;), (=&lt;&lt;), (&amp;&amp;), (||), (^), (^^), (.), ($), ($!), (++), (!!), Eq,
error, id, return, not, fst, snd, map, filter, concat, concatMap, reverse,
zip, null, takeWhile, dropWhile, all, any, Integer, negate, abs, divMod,
String, Bool(True, False), Maybe(Nothing, Just));
import qualified Prelude;
fold :: forall a b. (a -&gt; b -&gt; b) -&gt; [a] -&gt; b -&gt; b;
fold f (x : xs) s = fold f xs (f x s);
fold f [] s = s;
member :: forall a. (Eq a) =&gt; [a] -&gt; a -&gt; Bool;
member [] y = False;
member (x : xs) y = x == y || member xs y;
insert :: forall a. (Eq a) =&gt; a -&gt; [a] -&gt; [a];
insert x xs = (if member xs x then xs else x : xs);
removeAll :: forall a. (Eq a) =&gt; a -&gt; [a] -&gt; [a];
removeAll x [] = [];
removeAll x (y : xs) = (if x == y then removeAll x xs else y : removeAll x xs);
module Set(Set, bex, insert, member, bot_set, sup_set) where {
import Prelude ((==), (/=), (&lt;), (&lt;=), (&gt;=), (&gt;), (+), (-), (*), (/), (**),
(&gt;&gt;=), (&gt;&gt;), (=&lt;&lt;), (&amp;&amp;), (||), (^), (^^), (.), ($), ($!), (++), (!!), Eq,
error, id, return, not, fst, snd, map, filter, concat, concatMap, reverse,
zip, null, takeWhile, dropWhile, all, any, Integer, negate, abs, divMod,
String, Bool(True, False), Maybe(Nothing, Just));
import qualified Prelude;
import qualified List;
data Set a = Set [a] | Coset [a];
bex :: forall a. Set a -&gt; (a -&gt; Bool) -&gt; Bool;
bex (Set xs) p = any p xs;
insert :: forall a. (Eq a) =&gt; a -&gt; Set a -&gt; Set a;
insert x (Coset xs) = Coset (List.removeAll x xs);
insert x (Set xs) = Set (List.insert x xs);
member :: forall a. (Eq a) =&gt; a -&gt; Set a -&gt; Bool;
member x (Coset xs) = not (List.member xs x);
member x (Set xs) = List.member xs x;
bot_set :: forall a. Set a;
bot_set = Set [];
sup_set :: forall a. (Eq a) =&gt; Set a -&gt; Set a -&gt; Set a;
sup_set (Coset xs) a = Coset (filter (\ x -&gt; not (member x a)) xs);
sup_set (Set xs) a = List.fold insert xs a;
module Prover(Form, prover) where {
import Prelude ((==), (/=), (&lt;), (&lt;=), (&gt;=), (&gt;), (+), (-), (*), (/), (**),
(&gt;&gt;=), (&gt;&gt;), (=&lt;&lt;), (&amp;&amp;), (||), (^), (^^), (.), ($), ($!), (++), (!!), Eq,
error, id, return, not, fst, snd, map, filter, concat, concatMap, reverse,
zip, null, takeWhile, dropWhile, all, any, Integer, negate, abs, divMod,
String, Bool(True, False), Maybe(Nothing, Just));
import qualified Prelude;
import qualified Set;
data Form a = Atom Bool a | Op (Form a) Bool (Form a);
cal :: forall a. (Eq a) =&gt; (Set.Set a, Set.Set a) -&gt; [Form a] -&gt; Bool;
cal e [] = Set.bex (fst e) (\ n -&gt; Set.member n (snd e));
cal e (Atom b n : s) =
(if b then cal (Set.sup_set (Set.insert n Set.bot_set) (fst e), snd e) s
else cal (fst e, Set.sup_set (snd e) (Set.insert n Set.bot_set)) s);
cal e (Op p b q : s) =</p>
      <p>(if b then cal e (p : s) &amp;&amp; cal e (q : s) else cal e (p : q : s));
prover :: forall a. (Eq a) =&gt; Form a -&gt; Bool;
prover p = cal (Set.bot_set, Set.bot_set) [p];</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>Armin</given-names>
            <surname>Biere</surname>
          </string-name>
          , Marijn Heule, and Hans van Maaren.
          <article-title>Handbook of Satis ability</article-title>
          . IOS press,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>Jasmin</given-names>
            <surname>Christian</surname>
          </string-name>
          <article-title>Blanchette. Formalizing the metatheory of logical calculi and automatic provers in Isabelle/HOL (invited talk)</article-title>
          .
          <source>In Assia Mahboubi and Magnus O. Myreen</source>
          , editors,
          <source>Proceedings of the 8th ACM SIGPLAN International Conference on Certi ed Programs and Proofs</source>
          ,
          <string-name>
            <surname>CPP</surname>
          </string-name>
          <year>2019</year>
          , pages
          <fpage>1</fpage>
          <lpage>{</lpage>
          13. ACM,
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>Melvin</given-names>
            <surname>Fitting</surname>
          </string-name>
          .
          <article-title>leanTAP revisited</article-title>
          .
          <source>J. Log. Comput.</source>
          ,
          <volume>8</volume>
          (
          <issue>1</issue>
          ):
          <volume>33</volume>
          {
          <fpage>47</fpage>
          ,
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <surname>Asta Halkj</surname>
          </string-name>
          r From,
          <source>Alexander Birch Jensen</source>
          , Anders Schlichtkrull, and J rgen Villadsen.
          <article-title>Teaching a Formalized Logical Calculus</article-title>
          .
          <source>In Proceedings of the 8th International Workshop on Theorem proving components for Educational software (ThEdu'19)</source>
          ,
          <year>2020</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <given-names>Kurt</given-names>
            <surname>Go</surname>
          </string-name>
          <article-title>del. Uber die Vollstandigkeit des Logikkalkuls</article-title>
          .
          <source>PhD thesis</source>
          , University of Vienna,
          <year>1929</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <given-names>Leon</given-names>
            <surname>Henkin</surname>
          </string-name>
          .
          <article-title>The Completeness of Formal Systems</article-title>
          .
          <source>PhD thesis</source>
          , Princeton University,
          <year>1947</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>Alexander</given-names>
            <surname>Birch</surname>
          </string-name>
          <string-name>
            <surname>Jensen</surname>
          </string-name>
          , John Bruntse Larsen, Anders Schlichtkrull,
          <article-title>and J rgen Villadsen. Programming and verifying a declarative rst-order prover in Isabelle/HOL</article-title>
          .
          <source>AI Communications</source>
          ,
          <volume>31</volume>
          (
          <issue>3</issue>
          ):
          <volume>281</volume>
          {
          <fpage>299</fpage>
          ,
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <given-names>Ramana</given-names>
            <surname>Kumar</surname>
          </string-name>
          , Rob Arthan,
          <article-title>Magnus O Myreen,</article-title>
          and
          <string-name>
            <given-names>Scott</given-names>
            <surname>Owens</surname>
          </string-name>
          .
          <article-title>Selfformalisation of higher-order logic</article-title>
          .
          <source>Journal of Automated Reasoning</source>
          ,
          <volume>56</volume>
          (
          <issue>3</issue>
          ):
          <volume>221</volume>
          {
          <fpage>259</fpage>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9.
          <string-name>
            <given-names>Julius</given-names>
            <surname>Michaelis</surname>
          </string-name>
          and
          <string-name>
            <given-names>Tobias</given-names>
            <surname>Nipkow</surname>
          </string-name>
          .
          <article-title>Formalized proof systems for propositional logic</article-title>
          . In A.
          <string-name>
            <surname>Abel</surname>
            ,
            <given-names>F.</given-names>
          </string-name>
          <article-title>Nordvall Forsberg, and</article-title>
          <string-name>
            <surname>A</surname>
          </string-name>
          . Kaposi, editors,
          <source>23rd Int. Conf. Types for Proofs and Programs (TYPES</source>
          <year>2017</year>
          ), volume
          <volume>104</volume>
          <source>of LIPIcs</source>
          , pages
          <fpage>6</fpage>
          <issue>:1</issue>
          { 6:
          <fpage>16</fpage>
          .
          <string-name>
            <surname>Schloss</surname>
          </string-name>
          Dagstuhl - Leibniz-Zentrum fuer Informatik,
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <surname>Tobias</surname>
            <given-names>Nipkow</given-names>
          </string-name>
          , Lawrence C. Paulson, and Markus Wenzel.
          <article-title>Isabelle/HOL - A Proof Assistant for Higher-Order Logic</article-title>
          , volume
          <volume>2283</volume>
          of Lecture Notes in Computer Science. Springer,
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <surname>Lawrence</surname>
            <given-names>C. Paulson.</given-names>
          </string-name>
          <article-title>A machine-assisted proof of Godel's incompleteness theorems for the theory of hereditarily nite sets</article-title>
          .
          <source>The Review of Symbolic Logic</source>
          ,
          <volume>7</volume>
          (
          <issue>3</issue>
          ):
          <volume>484</volume>
          {
          <fpage>498</fpage>
          ,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12.
          <string-name>
            <given-names>Anders</given-names>
            <surname>Schlichtkrull</surname>
          </string-name>
          .
          <article-title>Formalization of the resolution calculus for rst-order logic</article-title>
          .
          <source>Journal of Automated Reasoning</source>
          ,
          <volume>61</volume>
          (
          <issue>1-4</issue>
          ):
          <volume>455</volume>
          {
          <fpage>484</fpage>
          ,
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <string-name>
            <given-names>Natarajan</given-names>
            <surname>Shankar</surname>
          </string-name>
          .
          <article-title>Towards mechanical metamathematics</article-title>
          .
          <source>Journal of Automated Reasoning</source>
          ,
          <volume>1</volume>
          (
          <issue>4</issue>
          ):
          <volume>407</volume>
          {
          <fpage>434</fpage>
          ,
          <year>1985</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14. Makarius Wenzel. Isabelle/Isar|
          <article-title>a generic framework for human-readable proof documents</article-title>
          . From Insight to Proof|Festschrift in Honour of Andrzej Trybulec,
          <volume>10</volume>
          (
          <issue>23</issue>
          ):
          <volume>277</volume>
          {
          <fpage>298</fpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15. Makarius Wenzel. The Isabelle/Isar Reference Manual.
          <article-title>Part of the Isabelle distribution</article-title>
          ,
          <year>2020</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16. Richard Zach.
          <article-title>Completeness before Post: Bernays, Hilbert, and the development of propositional logic</article-title>
          .
          <source>Bulletin of Symbolic Logic</source>
          ,
          <volume>5</volume>
          (
          <issue>3</issue>
          ):
          <volume>331</volume>
          {
          <fpage>366</fpage>
          ,
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>