TPTP Format for Derivations

Introduction

A derivation is a directed acyclic graph (DAG) whose leaf nodes are formulae from the input, whose interior nodes are formulae inferred from parent formulae, and whose root nodes are the final derived formulae. For example, a proof of a FOF theorem from some axioms, by refutation of the CNF of the axioms and negated conjecture, is a derivation whose leaf nodes are the FOF axioms and conjecture, whose internal nodes are formed from the process of clausification and then from inferences performed on the clauses, and whose root node is the false formula.

The information required to record a derivation is, minimally, the leaf formulae, and each inferred formula with references to its parent formulae. More detailed information that might be recorded and useful includes: the role of each formula; the name of the inference rule used in each inference step; sufficient details of each inference step to deterministically reproduce the inference; the semantic relationships of inferred formulae with respect to their parents.


Acceptable Derivations

The TPTP format requires certain features of a derivation so be deemed acceptable, e.g., as required by the
CADE ATP System Competition (CASC). Required features are expressed as "must" in the documentation below, and marked ❗). Other features that are desirable are expressed as "should" in the documentation below. ATP systems might usefully offer a flag to indicate whether just an acceptable derivation is required, or a really nice derivation.

Specifying a TPTP Format Derivation

The top level building blocks of TPTP derivations are
annotated formulae. An annotated formula has the form:

    language(name,role,formula,source,useful info). A derivation is written as a list of annotated formulae.

The source and useful information are optional.

Sources:


Definitions

If a derivation defines a new symbol, the definition annotated formula must have the following form:
(In problems definitions are axiom-like and do not need an introduced() record.)

Examples

tff(square,definition,
    ! [I: $int] :
      ( square(I) = $product(I,I) ),
    introduced(definition,[new_symbols(definition,[square])],[])).

fof(pugalist,definition,
    ( no_fighters <=> ! [X] : ~ has_job(X,boxer) ),
    introduced(definition,[new_symbols(definition,[no_fighters])],[])).

tff(bad_cat,definition,
    ! [C: cat] :
      ( ~ friendly(C) <=> ( horrible(C) & bad_pet(C) ) ),
    introduced(definition,[new_symbols(definition,[friendly])],[])).


Tautologies

If a derivation introduces a tautology, the annotated formula must have the following form:

Examples

tff(soliloquy,axiom,
    ! [X: alive] :
      ( to_be(X) | ~ to_be(X) ),
    introduced(tautology,[that_is_the_question],[hamlet])).


Theory Axioms

If a derivation introduces a theory axiom that has to be accepted on faith, e.g., arithmetic axioms, the annotated formula must have the following form:

Examples

tff(square_root_2,axiom,
    ~ ? [X: $rat] :
        $product(X,X) = 2,
    introduced(theory,[],[hippasus_of_metapontum])).


Skolemization

Each Skolemization step of one existentially quantified variable should be performed and recorded in a separate annotated formula. So far two variants have emerged, each of which has particular output requirements.

Plain example, single steps:

%----Starting formula
fof(marriage,plain,
    ! [Marriage] :
    ? [Bride] :
    ! [Parent] :
    ? [Groom] :
      ( in_love(Groom,Bride) 
     => give_hand_in_marriage(Parent,Bride,Groom,Marriage) ) ).

%----Skolemize Bride
fof(bride,plain,
    ! [Marriage] :
    ! [Parent] :
    ? [Groom] :
      ( in_love(Groom,sK0(Marriage))
     => give_hand_in_marriage(Parent,sK0(Marriage),Groom,Marriage) ),
    inference(skolemize,[status(esa),new_symbols(skolem,[sK0]),skolemize(Bride,sK0(Marriage))],[marriage]) ).

%----Skolemize Groom
fof(groom,plain,
    ! [Marriage] :
    ! [Parent] :
      ( in_love(sK1(Marriage,Parent),sK0(Marriage))
     => give_hand_in_marriage(Parent,sK0(Marriage),sK1(Marriage,Parent),Marriage) ),
    inference(skolemize,[status(esa),new_symbols(skolem,[sK1]),skolemize(Groom,sK1(Marriage,Parent))],[bride]) ).

"Hidden" existential quantification:
It is possible, but not nice, to record Skolemization steps with the existential quantification hidden, e.g., under a negated universal quantification.

fof(bride,plain,
    ! [Marriage] :
    ! [Parent] :
    ~ ! [Groom] :
        ~ ( in_love(Groom,sK0(Marriage))
         => give_hand_in_marriage(Parent,sK0(Marriage),Groom,Marriage) ) ).

%----Skolemize Groom
fof(groom,plain,
    ! [Marriage] :
    ! [Parent] :
      ~ ~ ( in_love(sK1(Marriage,Parent),sK0(Marriage))
         => give_hand_in_marriage(Parent,sK0(Marriage),sK1(Marriage,Parent),Marriage) ),
    inference(skolemize,[status(esa),new_symbols(skolem,[sK1]),skolemize(Groom,sK1(Marriage,Parent))],[bride]) ).

Plain example, multiple steps:
It is possible, but not nice, to record multiple Skolemization steps in one annotated formula.

%----Starting formula
fof(marriage,plain,
    ! [Marriage] :
    ? [Bride] :
    ! [Parent] :
    ? [Groom] :
      ( in_love(Groom,Bride) 
     => give_hand_in_marriage(Parent,Bride,Groom,Marriage) ) ).

%----Skolemize Bride and Groom
fof(groom,plain,
    ! [Marriage] :
    ! [Parent] :
      ( in_love(sK1(Marriage,Parent),sK0(Marriage))
     => give_hand_in_marriage(Parent,sK0(Marriage),sK1(Marriage,Parent),Marriage) ),
    inference(skolemize,[status(esa),new_symbols(skolem,[sk0,sK1]),skolemize(Bride,sK0(Marriage),skolemize(Groom,sK1(Marriage,Parent))],[marriage]) ).

Using ε-terms:
For people who justify Skolemization with ε-terms.

%----Starting formula
fof(marriage,plain,
    ! [Marriage] :
    ? [Bride] :
    ! [Parent] :
    ? [Groom] :
      ( in_love(Groom,Bride) 
     => give_hand_in_marriage(Parent,Bride,Groom,Marriage) ) ).

%----New symbol sK0 recorded here in the definition of the ε term. 
tff(sK0_defn,definition,
    ! [Marriage: $i] :
    ! [Parent: $i] :
      ( sK0(Marriage)
      = ( # [Bride: $i] :
          ? [Groom: $i] : 
            ( in_love(Groom,Bride)
           => give_hand_in_marriage(Parent,sK0(Marriage),Groom,Marriage) ) ),
    introduced(definition,[new_symbols(skolem,[sK0])],[marriage]) ).

%----Skolemize Bride
fof(bride,plain,
    ! [Marriage] :
    ! [Parent] :
    ? [Groom] :
      ( in_love(Groom,sK0(Marriage))
     => give_hand_in_marriage(Parent,sK0(Marriage),Groom,Marriage) ),
    inference(skolemize,[status(esa),skolemize(Bride,sK0(Marriage))],[marriage,sK0_defn]) ).

tff(sK1_defn,definition,
    ! [Marriage: $i] :
    ! [Parent: $i] :
      ( sK1(Marriage,Parent)
      = ( # [Groom: $i] : 
            ( in_love(Groom,sK0(Marriage))
           => give_hand_in_marriage(Parent,sK0(Marriage),sK1(Marriage,Parent),Marriage) ) ) ),
    introduced(definition,[new_symbols(skolem,[sK1])],[bride]) ).

%----Skolemize Groom
fof(groom,plain,
    ! [Marriage] :
    ! [Parent] :
      ( in_love(sK1(Marriage,Parent),sK0(Marriage))
     => give_hand_in_marriage(Parent,sK0(Marriage),sK1(Marriage,Parent),Marriage) ),
    inference(skolemize,[status(esa),skolemize(Bride,sK0(Marriage),skolemize(Groom,sK1(Marriage,Parent))],[bride,sK1_defn]) ).


New Symbol Names

These conventions provide guidelines for reasonable naming of such symbols, and specifiy how the new symbols must be introduced in inference() and introduced() records.

If you are interested in the history and motivations behind this convention, read the source of this web page.


Example Derivation

Consider the toy FOF problem
in the problem quick guide. Here is a derivation recording a proof by refutation of the CNF (adapted from the one produced by the ATP system E):
%------------------------------------------------------------------------------
fof(someone_not_john,conjecture,
    ? [X3] :
      ( human(X3)
      & created_equal(X3,john)
      & X3 != john ),
    file('CreatedEqual.p',someone_not_john) ).

fof(all_created_equal,axiom,
    ! [X1,X2] :
      ( ( human(X1)
        & human(X2) )
     => created_equal(X1,X2) ),
    file('CreatedEqual.p',all_created_equal) ).

fof(someone_got_an_a,axiom,
    ? [X3] :
      ( human(X3)
      & grade(X3) = a ),
    file('CreatedEqual.p',someone_got_an_a) ).

fof(john,axiom,
    human(john),
    file('CreatedEqual.p',john) ).

fof(distinct_grades,axiom,
    a != f,
    file('CreatedEqual.p',distinct_grades) ).

fof(john_failed,axiom,
    grade(john) = f,
    file('CreatedEqual.p',john_failed) ).

fof(c_0_6,negated_conjecture,
    ~ ? [X3] :
        ( human(X3)
        & created_equal(X3,john)
        & X3 != john ),
    inference(fof_simplification,[status(thm)],[inference(assume_negation,[status(cth)],[someone_not_john])]) ).

fof(c_0_7,plain,
    ! [X6,X7] :
      ( ~ human(X6)
      | ~ human(X7)
      | created_equal(X6,X7) ),
    inference(fof_nnf,[status(thm)],[inference(variable_rename,[status(thm)],[inference(fof_nnf,[status(thm)],[all_created_equal])])]) ).

fof(c_0_8,negated_conjecture,
    ! [X5] :
      ( ~ human(X5)
      | ~ created_equal(X5,john)
      | X5 = john ),
    inference(fof_nnf,[status(thm)],[inference(variable_rename,[status(thm)],[inference(fof_nnf,[status(thm)],[c_0_6])])]) ).

%----If E believed in epsilon terms ...
% tff(sK0_defn,definition,
%     ( sK0
%     = ( # [X3: $i] :
%           ( human(X3)
%           & ( grade(X3) = a ) ) ) ),
%     introduced(definition,[new_symbols(skolem,[sK0])],[someone_got_an_a]) ).

fof(c_0_9,plain,
    ( human(sK0)
    & grade(sK0) = a ),
    inference(skolemize,[status(esa),new_symbols(skolem,[sK0]),skolemize(X3,sK0)],[someone_got_an_a]) ).

cnf(c_0_10,plain,
    ( created_equal(X1,X2)
    | ~ human(X1)
    | ~ human(X2) ),
    inference(split_conjunct,[status(thm)],[c_0_7]) ).

cnf(c_0_11,plain,
    human(john),
    inference(split_conjunct,[status(thm)],[john]) ).

cnf(c_0_12,negated_conjecture,
    ( X1 = john
    | ~ human(X1)
    | ~ created_equal(X1,john) ),
    inference(split_conjunct,[status(thm)],[c_0_8]) ).

cnf(c_0_13,plain,
    human(sK0),
    inference(split_conjunct,[status(thm)],[c_0_9]) ).

cnf(c_0_14,plain,
    ( created_equal(X1,john)
    | ~ human(X1) ),
    inference(spm,[status(thm)],[c_0_10,c_0_11]) ).

fof(c_0_15,plain,
    a != f,
    inference(fof_simplification,[status(thm)],[distinct_grades]) ).

cnf(c_0_16,negated_conjecture,
    ( sK0 = john
    | ~ created_equal(sK0,john) ),
    inference(spm,[status(thm)],[c_0_12,c_0_13]) ).

cnf(c_0_17,plain,
    created_equal(sK0,john),
    inference(spm,[status(thm)],[c_0_14,c_0_13]) ).

fof(c_0_18,plain,
    a != f,
    inference(fof_nnf,[status(thm)],[c_0_15]) ).

cnf(c_0_19,plain,
    grade(sK0) = a,
    inference(split_conjunct,[status(thm)],[c_0_9]) ).

cnf(c_0_20,negated_conjecture,
    sK0 = john,
    inference(cn,[status(thm)],[inference(rw,[status(thm)],[c_0_16,c_0_17])]) ).

cnf(c_0_21,plain,
    grade(john) = f,
    inference(split_conjunct,[status(thm)],[john_failed]) ).

cnf(c_0_22,plain,
    a != f,
    inference(split_conjunct,[status(thm)],[c_0_18]) ).

cnf(c_0_23,plain,
    $false,
    inference(sr,[status(thm)],[inference(rw,[status(thm)],[inference(rw,[status(thm)],[c_0_19,c_0_20]),c_0_21]),c_0_22]),
    [proof] ).
%------------------------------------------------------------------------------

Checking a Derivation

To check the syntax of a derivation you can run it through tptp4X, available in
SystemOnTSTP. Select the "TSTP formulae" option and paste the formulae into the text box. Select "TPTP4X" as the system, and ensure that the "Output mode" is "System". Click "ProcessSolution". If the syntax is faulty you'll get an error massage.

You can download and install TPTP4X on your own Linux computer, from Github. You must get the JJParser submodule too, i.e.,
    git clone --recurse-submodules https://github.com/TPTPWorld/TPTP4X.

You can verify a derivation using GDV, also available in SystemOnTSTP. Select the "TSTP formulae" option and paste the formulae into the text box. Select "GDV" as the system, and ensure that the "Output mode" is "System". Click "ProcessSolution". It might take a while for output to appear. If the derivation is dubious or faulty, you'll get an WARNING/ERROR messages.

You can download and install GDV on your own Linux computer, from Github. You must get the JJParser submodule too, i.e.,
    git clone --recurse-submodules https://github.com/TPTPWorld/GDV.git.

For more information about GDV, you can read ...

@Article{Sut06,
    Author       = "Sutcliffe, G.",
    Year         = "2006",
    Title        = "{Semantic Derivation Verification}",
    Journal      = "International Journal on Artificial Intelligence Tools",
    Volume       = "15",
    Number       = "6",
    Pages        = "1053-1070"
}