Proof by Contradiction

Geoff Sutcliffe
University of Miami
geoff[@]cs.miami.edu

Introduction

Most proofs output from modern ATP systems are proofs by contradiction of the clause normal form of the axioms and negated conjecture. For example:
fof(a,axiom,
    a ).

fof(a_implies_b,axiom,
    a => b ).

fof(b,conjecture,
    b ).

fof(f1,negated_conjecture,
    ~b,
     inference(negate,[status(cth)],[b]) ).

cnf(c1,plain,
    a,
    inference(cnf,[status(thm)],[a]) ).

cnf(c2,plain,
    ~a | b,
    inference(cnf,[status(thm)],[a_implies_b]) ).

cnf(c3,plain,
    ~b,
    inference(cnf,[status(thm)],[f1]) ).

cnf(c4,plain,
    ~a,
    inference(resolution,[status(thm)],[c2,c3]) ).

cnf(c5,plain,
    $false,
    inference(resolution,[status(thm)],[c1,c4]) ).
The weakness of this form is that the theorem is not at the root, which means it is not possible to graft derivations together, with the proved root theorem of one being used as a lemma of the next.

A Better Way

A better way might be to do something similar to what is done in ND. The negated conjecture is introduced as an assumption, recorded as an assumption in all of its descendent formulae, and must be discharged by being added as the antecedent of an implication with the current formula as consequent. For example:
fof(a,axiom,
    a ).

fof(a_implies_b,axiom,
    a => b ).

fof(b,conjecture,
    b ).

fof(f1,assumption,
    ~b,
    introduced(assumption,[negate(b)]) ).

cnf(c1,plain,
    a,
    inference(cnf,[status(thm)],[a]) ).

cnf(c2,plain,
    ~a | b,
    inference(cnf,[status(thm)],[a_implies_b]) ).

cnf(c3,plain,
    ~b,
    inference(cnf,[status(thm),assumptions([f1])],[f1]) ).

cnf(c4,plain,
    ~a,
    inference(resolution,[status(thm),assumptions([f1])],[c2,c3]) ).

cnf(c5,plain,
    $false,
    inference(resolution,[status(thm),assumptions([f1])],[c1,c4]) ).

fof(f2,plain,
    ~b => $false,
    inference(discharge,[status(thm)],assumptions([])],[c5,f1]) ).

fof(f3,theorem,
    b,
    inference(simplify,[status(thm)],assumptions([])],[f2]) ).
This can also be used for recording explicit splits, as done by SPASS:
fof(a,axiom,
    a ).

fof(a_implies_b,axiom,
    a => b ).

fof(b,conjecture,
    b ).

fof(f1,assumption,
    ~b,
    introduced(assumption,[negate(b)]) ).

cnf(c1,plain,
    a,
    inference(cnf,[status(thm)],[a]) ).

cnf(c2,plain,
    ~a | b,
    inference(cnf,[status(thm)],[a_implies_b]) ).

cnf(c3,plain,
    ~b,
    inference(cnf,[status(thm),assumptions([f1])],[f1]) ).

cnf(c4,assumption,
    ~b,
    introduced(assumption,[split(c2)]) ).

cnf(c5,plain,
    ~a,
    inference(resolution,[status(thm),assumptions([c4])],[c2,c4]) ).

cnf(c6,plain,
    $false,
    inference(resolution,[status(thm),assumptions([c4])],[c1,c5]) ).

fof(f2,plain,
    ~b => $false,
    inference(discharge,[status(thm),assumptions([])],[c6,c4]) ).

fof(f3,plain,
    b,
    inference(simplify,[status(thm),assumptions([])],[f2]) ).

cnf(c7,plain,
    b,
    inference(cnf,[status(thm),assumptions([])],[f3]) ).

cnf(c8,plain,
    $false,
    inference(resolution,[status(thm),assumptions([f1])],[c3,c7]) ).

fof(f4,plain,
    ~b => $false,
    inference(discharge,[status(thm),assumptions([])],[c8,f1]) ).

fof(f5,theorem,
    b,
    inference(simplify,[status(thm),assumptions([])],[f4]) ).