Connect++ 0.7.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
FOF Class Reference

Representation of first order formulas. More...

#include <FOF.hpp>

Collaboration diagram for FOF:

Public Member Functions

 FOF ()=delete
 You don't want this constructor.
 
 FOF (FOFType t)
 You probably don't want this constructor.
 
 FOF (const Literal &)
 Construct FOF from Literal.
 
 FOF (FOFType, const vector< FOF > &, Variable *)
 Construct FOF for a non-literal.
 
void show_indexes () const
 Show the indices.
 
FOFType fof_type ()
 Basic get method.
 
void add_formula (const FOF &f)
 Add a subformula.
 
void clear ()
 Make an FOFType::Empty.
 
bool is_literal () const
 Check if an FOF is a literal.
 
bool is_clause () const
 Check if something is a clause.
 
void remove_negation ()
 Remove the leading negation from an arbitrary FOF, if it has one.
 
void negate ()
 Negate an FOF, applying obvious simplifications if it's already negated or an implication.
 
void simple_negate ()
 Negate an FOF without applying any simplifications.
 
void invert_literal ()
 Self-explanatory!
 
void remove_iff ()
 Replace <-> throughout using ->.
 
void remove_imp ()
 Replace A->B throughout with neg A v B.
 
void make_unique_bound_variables ()
 Replace all bound variables with unique new ones.
 
void remove_redundant_quantifiers ()
 Remove quantifiers if they don't bind anything in their scope.
 
void push_negs ()
 Push all negations in.
 
void convert_to_nnf ()
 Convert to Negation Normal Form.
 
void miniscope ()
 Apply the rules for miniscoping.
 
void convert_to_cnf_clauses (vector< Clause > &, vector< string > &, const string &)
 Convert to Conjunctive Normal Form.
 
void split_sub_formulas (vector< FOF > &, vector< FOF > &)
 Split subformulas in half.
 
void find_definitional_tuple (FOF &, vector< FOF > &, vector< FOF > &, bool)
 Heavy-lifting for conversion to definitional clause form.
 
void definitional_convert_to_cnf_clauses (vector< Clause > &, vector< string > &, const string &)
 Convert to Conjunctive Normal Form using a form of definitional conversion.
 
void skolemize ()
 Skolemize the given formula.
 
void remove_universal_quantifiers ()
 Self-explanatory.
 
void skolemize_universals ()
 Skolemize the universal quantifiers in the given formula.
 
void remove_existential_quantifiers ()
 Self-explanatory.
 
void to_Literal (Literal &) const
 Assuming the FOF is a literal, convert it to something of type Literal.
 
void convert_to_clauses (vector< Clause > &) const
 Assuming you have a CNF, convert it to a collection of Clauses.
 
void dnf_invert_and_convert_to_clauses (vector< Clause > &) const
 Assuming you have a DNF, invert it and convert it to a collection of CNF clauses.
 
size_t find_and () const
 Does the collection of subformulas contain an AND? If so, find it.
 
size_t find_or () const
 Does the collection of subformulas contain an OR? If so, find it.
 
void distribute_or ()
 Distribute ORs to the maximum extent possible.
 
void distribute_and ()
 Distribute ANDs to the maximum extent possible.
 
string to_string () const
 Convert a FOF into a nice-looking string.
 
string to_tptp_string (bool=false) const
 Convert a FOF into a nice-looking string in the TPTP format.
 
string predicate_to_tptp_string () const
 Assuming this is an Atom, return the predicate name as a string.
 
set< Term * > find_free_variables () const
 Find the free variables in the formula.
 

Static Public Member Functions

static void set_indexes (std::tuple< VariableIndex *, FunctionIndex *, PredicateIndex *, TermIndex * > is)
 Set up pointer to the variable index etc.
 
static void set_recs_p (TPTPRecords *_p)
 Set up the pointer allowing TPTP outputs to be added.
 
static FOF make_literal (const Literal &lit)
 Directly make a Literal.
 
static FOF make_neg (const FOF &f)
 Directly negate a FOF.
 
static FOF make_and (const vector< FOF > &fs)
 Directly make a conjunction.
 
static FOF make_or (const vector< FOF > &fs)
 Directly make a disjunction.
 
static FOF make_imp (const FOF &lhs, const FOF &rhs)
 Directly make an implication.
 
static FOF make_iff (const FOF &lhs, const FOF &rhs)
 Directly make an iff.
 
static FOF make_forall (const FOF &f, Variable *v)
 Directly make a universally quantified FOF.
 
static FOF make_exists (const FOF &f, Variable *v)
 Directly make an existentially quantified FOF.
 
static SimplificationResult simplify_cnf (vector< Clause > &)
 Simplify the clauses in a CNF using the method in Clause.
 
static SimplificationResult simplify_cnf (vector< Clause > &, vector< string > &, vector< string > &)
 As first version of simplify_cnf, but keep track of corresponding roles as well.
 

Private Member Functions

bool has_free_variable (Variable *)
 Does this formula contain the specified variable unbound?
 
void replace_variable (Variable *, Variable *)
 Self-explanatory.
 
Termmake_skolem_function (const vector< Term * > &)
 Make a new Skolem function.
 
void replace_variable_with_term (Term *, Variable *)
 Replace a Variable with a Term.
 
void skolemize_main (vector< Term * >, FOF *, bool=false)
 Main helper function called by FOF::skolemize().
 
void skolemize_universals_main (vector< Term * >, FOF *, bool=false)
 The dual of skolemize_main.
 
void miniscope_split (Variable *, vector< FOF > &, vector< FOF > &)
 Helper for miniscope.
 
void miniscope_all ()
 Apply miniscoping to all subformulas.
 
FOF make_definitional_predicate () const
 When doing definitional clause conversion you need to be able to make unique new predicates. This will provide one.
 
bool distribute_or_once ()
 Find an OR that can be distributed and deal with it. Indicate if there isn't one.
 
bool distribute_and_once ()
 Find an AND that can be distributed and deal with it. Indicate if there isn't one.
 

Private Attributes

FOFType type
 Used for all FOFs to denote what kind it it.
 
Literal pred
 FOFType::Atom can store one of these to represent a Literal.
 
vector< FOFsub_formulas
 Most FOFs will have subformulas.
 
Variablevar
 Associate a Variable with a quantifier.
 

Static Private Attributes

static TPTPRecordsrecs_p = nullptr
 Allow FOF to add TPTP outputs.
 
static VariableIndexvar_index = nullptr
 Access to the index: static because all FOFs should share it.
 
static FunctionIndexfun_index = nullptr
 Access to the index: static because all FOFs should share it.
 
static TermIndexterm_index = nullptr
 Access to the index: static because all FOFs should share it.
 
static PredicateIndexpred_index = nullptr
 Access to the index: static because all FOFs should share it.
 

Friends

ostream & operator<< (ostream &out, const FOF &f)
 

Detailed Description

Representation of first order formulas.

First and foremost: I intensely dislike the use of inheritance. I vastly prefer to make the methods static and do everything the obvioous way. If you want the alternative sort of OO, then feel free to implement this yourself.

This has to play nicely with the parser and with the indexing of terms, variables and so on, so it needs pointers to the relevant indices.

Definition at line 58 of file FOF.hpp.

Constructor & Destructor Documentation

◆ FOF() [1/3]

FOF::FOF ( FOFType t)
inline

You probably don't want this constructor.

Definition at line 219 of file FOF.hpp.

220 : type(t), pred(), sub_formulas(), var(nullptr) {}
Variable * var
Associate a Variable with a quantifier.
Definition FOF.hpp:80
FOFType type
Used for all FOFs to denote what kind it it.
Definition FOF.hpp:67
vector< FOF > sub_formulas
Most FOFs will have subformulas.
Definition FOF.hpp:76
Literal pred
FOFType::Atom can store one of these to represent a Literal.
Definition FOF.hpp:72

◆ FOF() [2/3]

FOF::FOF ( const Literal & lit)

Construct FOF from Literal.

Parameters
litReference to Literal to use.

Definition at line 347 of file FOF.cpp.

348: sub_formulas()
349, var(nullptr)
350{
351 if (lit.is_positive()) {
352 type = FOFType::Atom;
353 pred = lit;
354 }
355 else {
356 pred.clear();
357 type = FOFType::Neg;
358 Literal lit_copy = lit;
359 lit_copy.make_positive();
360 FOF f(lit_copy);
361 sub_formulas.push_back(f);
362 }
363}
Representation of first order formulas.
Definition FOF.hpp:58
Basic representation of literals, bundling together (pointers to) a Predicate, a collection of argume...
Definition Literal.hpp:50
void make_positive()
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:99
bool is_positive() const
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:91
void clear()
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:119

◆ FOF() [3/3]

FOF::FOF ( FOFType t,
const vector< FOF > & sf,
Variable * v )

Construct FOF for a non-literal.

Parameters
tSpecify FOFType for what you're making.
sfReference to vector of FOF for subformulas.
vPointer to Variable.

Definition at line 365 of file FOF.cpp.

366: type(t)
367, pred()
368, sub_formulas(sf)
369, var(v)
370{
371 switch (t) {
372 case FOFType::Atom:
373 cerr << "Stop it! You can't make an atom with this constructor!" << endl;
374 break;
375 case FOFType::Neg:
376 case FOFType::And:
377 case FOFType::Or:
378 case FOFType::Imp:
379 case FOFType::Iff:
380 // Easy as the work gets done above.
381 if (var != nullptr) {
382 cerr << "Are you sure you want to associate a variable with something that's not a quantifier?" << endl;
383 var = nullptr;
384 }
385 break;
386 case FOFType::A:
387 case FOFType::E:
388 if (sf.size() != 1) {
389 cerr << "Careful! A quantifier should only have one subformula." << endl;
390 }
391 if (v == nullptr) {
392 cerr << "Careful! A quantifier needs a variable." << endl;
393 }
394 break;
395 default:
396 break;
397 }
398}

Member Function Documentation

◆ add_formula()

void FOF::add_formula ( const FOF & f)
inline

Add a subformula.

Definition at line 272 of file FOF.hpp.

272{ sub_formulas.push_back(f); }

◆ clear()

void FOF::clear ( )
inline

Make an FOFType::Empty.

Definition at line 276 of file FOF.hpp.

276 {
277 type = FOFType::Empty;
278 pred.clear();
279 sub_formulas.clear();
280 var = nullptr;
281 }

◆ convert_to_clauses()

void FOF::convert_to_clauses ( vector< Clause > & cs) const

Assuming you have a CNF, convert it to a collection of Clauses.

Definition at line 1169 of file FOF.cpp.

1169 {
1170 cs.clear();
1171 if (is_literal()) {
1172 Literal new_lit;
1173 to_Literal(new_lit);
1174 Clause new_c;
1175 new_c.add_lit(new_lit);
1176 cs.push_back(new_c);
1177 return;
1178 }
1179 if (type == FOFType::Or) {
1180 vector<Clause> c;
1181 Clause new_c;
1182 cs.push_back(new_c);
1183 for (size_t i = 0; i < sub_formulas.size(); i++) {
1184 sub_formulas[i].convert_to_clauses(c);
1185 for (size_t j = 0; j < c[0].size(); j++) {
1186 cs[0].add_lit((c[0])[j]);
1187 }
1188 }
1189 return;
1190 }
1191 if (type == FOFType::And) {
1192 vector<Clause> c;
1193 for (size_t i = 0; i < sub_formulas.size(); i++) {
1194 sub_formulas[i].convert_to_clauses(c);
1195 for (size_t j = 0; j < c.size();j++) {
1196 cs.push_back(c[j]);
1197 }
1198 }
1199 }
1200}
Representation of clauses.
Definition Clause.hpp:52
void add_lit(const Literal &)
Add a literal, making sure you don't duplicate.
Definition Clause.cpp:96
void to_Literal(Literal &) const
Assuming the FOF is a literal, convert it to something of type Literal.
Definition FOF.cpp:1159
bool is_literal() const
Check if an FOF is a literal.
Definition FOF.cpp:402

◆ convert_to_cnf_clauses()

void FOF::convert_to_cnf_clauses ( vector< Clause > & cs,
vector< string > & _names,
const string & _role )

Convert to Conjunctive Normal Form.

Follow the usual recipe (Larry's lecture notes.) BUT there are lots of ways to do this—at present there is nothing sophisticated happening, and the approach is entirely obvious/straightforward. Also, this implementation does miniscoping.

Parameters
csvector of clauses containing the CNF.

Definition at line 817 of file FOF.cpp.

817 {
818 if (type == FOFType::Empty) {
819 cerr << "Don't do this with an Empty FOF!" << endl;
820 return;
821 }
822#ifdef DEBUGOUTPUT
823 cout << "Remove iff:" << endl;
824#endif
825 remove_iff();
826#ifdef DEBUGOUTPUT
827 cout << *this << endl;
828 cout << "Remove imp" << endl;
829#endif
830 remove_imp();
831#ifdef DEBUGOUTPUT
832 cout << *this << endl;
833 cout << "Push negs:" << endl;
834#endif
835 push_negs();
836 recs_p->add_fof_inference_record("fof_nnf,[status(thm)]",
837 this->to_tptp_string());
838
839#ifdef DEBUGOUTPUT
840 cout << *this << endl;
841 cout << "Make unique vars:" << endl;
842#endif
844 recs_p->add_fof_inference_record("variable_rename,[status(thm)]",
845 this->to_tptp_string());
846#ifdef DEBUGOUTPUT
847 cout << *this << endl;
848 cout << "Remove redundant quantifiers:" << endl;
849#endif
851#ifdef DEBUGOUTPUT
852 cout << *this << endl;
853 cout << "Miniscope:" << endl;
854#endif
855 if (params::miniscope) {
856 miniscope();
857 }
858 recs_p->add_fof_inference_record("miniscope,[status(thm)]",
859 this->to_tptp_string());
860#ifdef DEBUGOUTPUT
861 cout << *this << endl;
862 cout << "Skolemize:" << endl;
863#endif
864 skolemize();
865#ifdef DEBUGOUTPUT
866 cout << *this << endl;
867 cout << "Remove universal quantifiers:" << endl;
868#endif
870#ifdef DEBUGOUTPUT
871 cout << *this << endl;
872 cout << "Distribute or:" << endl;
873#endif
875#ifdef DEBUGOUTPUT
876 cout << *this << endl;
877 cout << "Convert to clauses:" << endl;
878#endif
880 for (const Clause& c : cs) {
881 string role = _role;
882 if (_role != string("negated_conjecture"))
883 role = "plain";
884 string name = recs_p->add_clause_record(c, role);
885 _names.push_back(name);
886 }
887#ifdef DEBUGOUTPUT
888 cout << *this << endl;
889#endif
890}
void skolemize()
Skolemize the given formula.
Definition FOF.cpp:1093
void remove_iff()
Replace <-> throughout using ->.
Definition FOF.cpp:474
string to_tptp_string(bool=false) const
Convert a FOF into a nice-looking string in the TPTP format.
Definition FOF.cpp:1345
void remove_redundant_quantifiers()
Remove quantifiers if they don't bind anything in their scope.
Definition FOF.cpp:544
void make_unique_bound_variables()
Replace all bound variables with unique new ones.
Definition FOF.cpp:519
void remove_universal_quantifiers()
Self-explanatory.
Definition FOF.cpp:1103
void miniscope()
Apply the rules for miniscoping.
Definition FOF.cpp:648
void push_negs()
Push all negations in.
Definition FOF.cpp:573
void convert_to_clauses(vector< Clause > &) const
Assuming you have a CNF, convert it to a collection of Clauses.
Definition FOF.cpp:1169
void remove_imp()
Replace A->B throughout with neg A v B.
Definition FOF.cpp:501
void distribute_or()
Distribute ORs to the maximum extent possible.
Definition FOF.cpp:1259
static TPTPRecords * recs_p
Allow FOF to add TPTP outputs.
Definition FOF.hpp:63

◆ convert_to_nnf()

void FOF::convert_to_nnf ( )

Convert to Negation Normal Form.

Follows the usual recipe (Larry's lecture notes.)

Definition at line 638 of file FOF.cpp.

638 {
639 if (type == FOFType::Empty) {
640 cerr << "Don't do this with an Empty FOF!" << endl;
641 return;
642 }
643 remove_iff();
644 remove_imp();
645 push_negs();
646}

◆ definitional_convert_to_cnf_clauses()

void FOF::definitional_convert_to_cnf_clauses ( vector< Clause > & cs,
vector< string > & _names,
const string & _role )

Convert to Conjunctive Normal Form using a form of definitional conversion.

There are lots of ways of doing definitional conversion. However as the restricted backtracking paper describing leanCoP v2.1 gives experimental results demonstrating that a particular approach is preferred, this implements the method as described in that paper.

Parameters
csvector of clauses containing the CNF.
See also
find_definitional_tuple

Definition at line 984 of file FOF.cpp.

984 {
985 if (type == FOFType::Empty) {
986 cerr << "Don't do this with an Empty FOF!" << endl;
987 return;
988 }
989 /*
990 * Note that the description in the restricted backtracking paper produces a
991 * DNF and starts with a Skolemized NNF of the original formula, *not* its
992 * negation. As the difference between this and the current representation, for
993 * connection calculus is just that all the literals get negated, this could
994 * be done more efficiently, but for now I'm going to just do a direct
995 * implementation of the procedure described in the paper. So: negate
996 * first, produce a DNF, then negate again.
997 */
999
1000 recs_p->add_fof_inference_record("def_negate,[status(cth)]",
1001 this->to_tptp_string());
1002
1003 remove_iff();
1004 remove_imp();
1005 push_negs();
1006
1007 recs_p->add_fof_inference_record("fof_nnf,[status(thm)]",
1008 this->to_tptp_string());
1009
1011
1012 recs_p->add_fof_inference_record("variable_rename,[status(thm)]",
1013 this->to_tptp_string());
1014
1016 /*
1017 * As we're producing a DNF, we skolemize universals and then remove existentials.
1018 */
1021 /*
1022 * Now we do the definitional magic.
1023 */
1024 FOF f(FOFType::Empty);
1025 vector<FOF> d;
1026 vector<FOF> d_preds;
1027 find_definitional_tuple(f, d, d_preds, false);
1028 /*
1029 * f is a DNF so we can invert it and flatten it to
1030 * the required CNF.
1031 */
1032 f.dnf_invert_and_convert_to_clauses(cs);
1033 /*
1034 * Each element of d now needs to be converted using
1035 * a standard conversion, then inverted and transformed
1036 * to CNF.
1037 */
1038 for (FOF& formula : d) {
1039 vector<Clause> new_cs;
1040 formula.distribute_and();
1041 formula.dnf_invert_and_convert_to_clauses(new_cs);
1042 for (const Clause& new_c : new_cs) {
1043 cs.push_back(new_c);
1044 }
1045 }
1046 /*
1047 * TPTP has no dnf() way of doing things. D'Oh! So I need a way of
1048 * making TPTP format output. Do the negation and make the clauses
1049 * for cnf. Then use their conjunction to output the new symbols
1050 * introduced but as CTP, which it is with respect to the herbrand step.
1051 * Then the individual clauses are THM.
1052 */
1053 /*
1054 * First make a cnf formula but in an fof format with quantifiers.
1055 */
1056 string tptp_fof_string("( ");
1057 int remaining = cs.size();
1058 for (const Clause& c : cs) {
1059 tptp_fof_string += c.to_tptp_fof_string();
1060 if (--remaining > 0) {
1061 tptp_fof_string += " & ";
1062 }
1063 }
1064 tptp_fof_string += " )";
1065 /*
1066 * Now you can construct the necessary TPTP format proof output. This
1067 * is where you also report any new symbols.
1068 */
1069 string role = _role;
1070 if (_role != string("negated_conjecture"))
1071 role = "plain";
1072
1073 string def_symbols;
1074 if (d_preds.size() > 0) {
1075 def_symbols += "[";
1076 commas::comma com(d_preds.size());
1077 for (const FOF& f : d_preds) {
1078 def_symbols += f.predicate_to_tptp_string();
1079 def_symbols += com();
1080 }
1081 def_symbols += "]";
1082 }
1083 recs_p->add_definitional_record(tptp_fof_string, def_symbols);
1084 /*
1085 * Now make what you actually need in cnf format.
1086 */
1087 for (const Clause& c : cs) {
1088 string name = recs_p->add_clause_record(c, role);
1089 _names.push_back(name);
1090 }
1091}
void skolemize_universals()
Skolemize the universal quantifiers in the given formula.
Definition FOF.cpp:1098
void find_definitional_tuple(FOF &, vector< FOF > &, vector< FOF > &, bool)
Heavy-lifting for conversion to definitional clause form.
Definition FOF.cpp:916
void simple_negate()
Negate an FOF without applying any simplifications.
Definition FOF.cpp:453
void remove_existential_quantifiers()
Self-explanatory.
Definition FOF.cpp:1131
Simple function object for putting commas in lists.

◆ distribute_and()

void FOF::distribute_and ( )

Distribute ANDs to the maximum extent possible.

Assumes you have nothing but a quantifier-free DNF in NNF. The result will have a tree structure with ORs at the top, then ANDs, then literals.

Definition at line 1263 of file FOF.cpp.

1263 {
1264 while (distribute_and_once()) {};
1265}
bool distribute_and_once()
Find an AND that can be distributed and deal with it. Indicate if there isn't one.
Definition FOF.cpp:150

◆ distribute_and_once()

bool FOF::distribute_and_once ( )
private

Find an AND that can be distributed and deal with it. Indicate if there isn't one.

Definition at line 150 of file FOF.cpp.

150 {
151 // For literals there is nothing to do.
152 if (is_literal()) {
153 return false;
154 }
155 // If we're at an OR, or an AND with no OR immediately under it,
156 // then we're just going to deal with the subformulas.
157 size_t or_location = find_or();
158 size_t s = sub_formulas.size();
159 if (type == FOFType::Or ||
160 ((type == FOFType::And) && (or_location == s))) {
161 bool result = false;
162 // OK, so it's not, strictly speaking, just "once" but
163 // we don't really mind do we?
164 for (size_t i = 0; i < s; i++) {
166 result = true;
167 }
168 return result;
169 }
170 // It must be an AND with an OR immediately under it. That means
171 // we can distribute. First get the OR's subformulas and
172 // remove it.
173 vector<FOF> or_fof_subs = sub_formulas[or_location].sub_formulas;
174 if (or_location != (s-1)) {
175 sub_formulas[or_location] = sub_formulas[s-1];
176 }
177 sub_formulas.pop_back();
178 // Now you've saved the sub-formulas for the OR, and
179 // removed it. The last remaining child of the AND is
180 // now going to be combined using AND with all
181 // the saved subformulas.
182 FOF f = sub_formulas[s-2];
183 size_t s2 = or_fof_subs.size();
184 vector<FOF> new_sub_formulas_2;
185 for (int i = 0; i < s2; i++) {
186 vector<FOF> new_sub_formulas;
187 new_sub_formulas.push_back(f);
188 new_sub_formulas.push_back(or_fof_subs[i]);
189 new_sub_formulas_2.push_back(FOF::make_and(new_sub_formulas));
190 }
191 // You may have started with an AND with only two children. If so
192 // then you can now move the OR upwards.
193 if (s == 2) {
194 type = FOFType::Or;
195 sub_formulas = new_sub_formulas_2;
196 }
197 else {
198 sub_formulas[s-2] = FOF::make_or(new_sub_formulas_2);
199 }
200 return true;
201}
static FOF make_or(const vector< FOF > &fs)
Directly make a disjunction.
Definition FOF.hpp:313
size_t find_or() const
Does the collection of subformulas contain an OR? If so, find it.
Definition FOF.cpp:1249
static FOF make_and(const vector< FOF > &fs)
Directly make a conjunction.
Definition FOF.hpp:306

◆ distribute_or()

void FOF::distribute_or ( )

Distribute ORs to the maximum extent possible.

Assumes you have nothing but a quantifier-free NNF. The result will have a tree structure with ANDs at the top, then ORs, then literals.

Definition at line 1259 of file FOF.cpp.

1259 {
1260 while (distribute_or_once()) {};
1261}
bool distribute_or_once()
Find an OR that can be distributed and deal with it. Indicate if there isn't one.
Definition FOF.cpp:97

◆ distribute_or_once()

bool FOF::distribute_or_once ( )
private

Find an OR that can be distributed and deal with it. Indicate if there isn't one.

Definition at line 97 of file FOF.cpp.

97 {
98 // For literals there is nothing to do.
99 if (is_literal()) {
100 return false;
101 }
102 // If we're at an AND, or an OR with no AND immediately under it,
103 // then we're just going to deal with the subformulas.
104 size_t and_location = find_and();
105 size_t s = sub_formulas.size();
106 if (type == FOFType::And ||
107 ((type == FOFType::Or) && (and_location == s))) {
108 bool result = false;
109 // OK, so it's not, strictly speaking, just "once" but
110 // we don't really mind do we?
111 for (size_t i = 0; i < s; i++) {
113 result = true;
114 }
115 return result;
116 }
117 // It must be an OR with an AND immediately under it. That means
118 // we can distribute. First get the AND's subformulas and
119 // remove it.
120 vector<FOF> and_fof_subs = sub_formulas[and_location].sub_formulas;
121 if (and_location != (s-1)) {
122 sub_formulas[and_location] = sub_formulas[s-1];
123 }
124 sub_formulas.pop_back();
125 // Now you've saved the sub-formulas for the AND, and
126 // removed it. The last remaining child of the OR is
127 // now going to be combined using OR with all
128 // the saved subformulas.
129 FOF f = sub_formulas[s-2];
130 size_t s2 = and_fof_subs.size();
131 vector<FOF> new_sub_formulas_2;
132 for (int i = 0; i < s2; i++) {
133 vector<FOF> new_sub_formulas;
134 new_sub_formulas.push_back(f);
135 new_sub_formulas.push_back(and_fof_subs[i]);
136 new_sub_formulas_2.push_back(FOF::make_or(new_sub_formulas));
137 }
138 // You may have started with an OR with only two children. If so
139 // then you can now move the AND upwards.
140 if (s == 2) {
141 type = FOFType::And;
142 sub_formulas = new_sub_formulas_2;
143 }
144 else {
145 sub_formulas[s-2] = FOF::make_and(new_sub_formulas_2);
146 }
147 return true;
148}
size_t find_and() const
Does the collection of subformulas contain an AND? If so, find it.
Definition FOF.cpp:1239

◆ dnf_invert_and_convert_to_clauses()

void FOF::dnf_invert_and_convert_to_clauses ( vector< Clause > & cs) const

Assuming you have a DNF, invert it and convert it to a collection of CNF clauses.

Definition at line 1202 of file FOF.cpp.

1202 {
1203 cs.clear();
1204 if (is_literal()) {
1205 Literal new_lit;
1206 to_Literal(new_lit);
1207 // This is where the inversion happens.
1208 new_lit.invert();
1209 Clause new_c;
1210 new_c.add_lit(new_lit);
1211 cs.push_back(new_c);
1212 return;
1213 }
1214 // Anything under here is essentially ANDed literals.
1215 if (type == FOFType::And) {
1216 vector<Clause> c;
1217 Clause new_c;
1218 cs.push_back(new_c);
1219 for (size_t i = 0; i < sub_formulas.size(); i++) {
1220 sub_formulas[i].dnf_invert_and_convert_to_clauses(c);
1221 for (size_t j = 0; j < c[0].size(); j++) {
1222 cs[0].add_lit((c[0])[j]);
1223 }
1224 }
1225 return;
1226 }
1227 // Anything below here essentially converts to another DNF.
1228 if (type == FOFType::Or) {
1229 vector<Clause> c;
1230 for (size_t i = 0; i < sub_formulas.size(); i++) {
1231 sub_formulas[i].dnf_invert_and_convert_to_clauses(c);
1232 for (size_t j = 0; j < c.size();j++) {
1233 cs.push_back(c[j]);
1234 }
1235 }
1236 }
1237}
void invert()
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:107

◆ find_and()

size_t FOF::find_and ( ) const

Does the collection of subformulas contain an AND? If so, find it.

Note: does not do any recursion – only looks at the top level.

Definition at line 1239 of file FOF.cpp.

1239 {
1240 size_t s = sub_formulas.size();
1241 for (size_t i = 0; i < s; i++) {
1242 if (sub_formulas[i].type == FOFType::And) {
1243 return i;
1244 }
1245 }
1246 return s;
1247}

◆ find_definitional_tuple()

void FOF::find_definitional_tuple ( FOF & f,
vector< FOF > & d,
vector< FOF > & d_preds,
bool in_conjunction )

Heavy-lifting for conversion to definitional clause form.

Parameters
fFirst part of definitional tuple.
dSecond part of definitional tuple.
d_predsCollects any new predicates introduced.
in_conjunctionmIndicates whether or not the parent formula was a conjunction.

Definition at line 916 of file FOF.cpp.

916 {
917 f.clear();
918 d.clear();
919 // Literals are straightforward.
920 if (is_literal()) {
921 f = *this;
922 vector<FOF> new_d;
923 d = new_d;
924 return;
925 }
926 // You must have an And or an Or because we're in NNF.
927 // Let's split half and half, just for the sake of symmetry.
928 vector<FOF> left;
929 vector<FOF> right;
930 split_sub_formulas(left, right);
931 FOF l = left[0];
932 FOF r = right[0];
933 if (left.size() > 1) {
934 l = FOF(type, left, nullptr);
935 }
936 if (right.size() > 1) {
937 r = FOF(type, right, nullptr);
938 }
939 // Somewhere to store results.
940 FOF new_f_1(FOFType::Empty);
941 FOF new_f_2(FOFType::Empty);
942 vector<FOF> new_d_1;
943 vector<FOF> new_d_2;
944 // The tricky case is an Or inside an And.
945 if (in_conjunction && type == FOFType::Or) {
946 l.find_definitional_tuple(new_f_1, new_d_1, d_preds, false);
947 r.find_definitional_tuple(new_f_2, new_d_2, d_preds, false);
949 f = def;
950 d_preds.push_back(def);
951
952 def.simple_negate();
953 vector<FOF> args1;
954 args1.push_back(def);
955 args1.push_back(new_f_1);
956 d.push_back(FOF::make_and(args1));
957 vector<FOF> args2;
958 args2.push_back(def);
959 args2.push_back(new_f_2);
960 d.push_back(FOF::make_and(args2));
961 for (const FOF& g : new_d_1) {
962 d.push_back(g);
963 }
964 for (const FOF& g : new_d_2) {
965 d.push_back(g);
966 }
967 return;
968 }
969 // The final case is straightforward.
970 bool is_and(type == FOFType::And);
971 l.find_definitional_tuple(new_f_1, new_d_1, d_preds, is_and);
972 r.find_definitional_tuple(new_f_2, new_d_2, d_preds, is_and);
973 vector<FOF> new_args;
974 new_args.push_back(new_f_1);
975 new_args.push_back(new_f_2);
976 FOF new_f(type, new_args, nullptr);
977 f = new_f;
978 d = new_d_1;
979 for (const FOF& g : new_d_2){
980 d.push_back(g);
981 }
982}
void clear()
Make an FOFType::Empty.
Definition FOF.hpp:276
void split_sub_formulas(vector< FOF > &, vector< FOF > &)
Split subformulas in half.
Definition FOF.cpp:892
FOF make_definitional_predicate() const
When doing definitional clause conversion you need to be able to make unique new predicates....
Definition FOF.cpp:87
FOF()=delete
You don't want this constructor.

◆ find_free_variables()

set< Term * > FOF::find_free_variables ( ) const

Find the free variables in the formula.

Note: will consider x to be free in:

( P(x) | Ax. Q(x) ).

Definition at line 1511 of file FOF.cpp.

1511 {
1512 set<Term*> result;
1513 set<Term*> free;
1514 Term* to_remove;
1515 switch (type) {
1516 case FOFType::Empty:
1517 cerr << "You shouldn't be doing this with an FOFType::Empty!" << endl;
1518 break;
1519 case FOFType::Atom:
1520 for (const Term* p : pred.get_args()) {
1521 free = p->all_variables();
1522 result.insert(free.begin(), free.end());
1523 }
1524 break;
1525 case FOFType::Neg:
1526 case FOFType::And:
1527 case FOFType::Or:
1528 case FOFType::Imp:
1529 case FOFType::Iff:
1530 for (const FOF& f : sub_formulas) {
1531 free = f.find_free_variables();
1532 result.insert(free.begin(), free.end());
1533 }
1534 break;
1535 case FOFType::A:
1536 case FOFType::E:
1537 result = sub_formulas[0].find_free_variables();
1538 to_remove = term_index->add_variable_term(var);
1539 result.erase(to_remove);
1540 break;
1541 default:
1542 break;
1543 }
1544 return result;
1545}
static TermIndex * term_index
Access to the index: static because all FOFs should share it.
Definition FOF.hpp:95
const vector< Term * > & get_args() const
Basic get method.
Definition Literal.hpp:83
General representation of terms.
Definition Term.hpp:62
Term * add_variable_term(Variable *)
Self-explanatory: add a Term containing a variable to the index.
Definition TermIndex.cpp:41

◆ find_or()

size_t FOF::find_or ( ) const

Does the collection of subformulas contain an OR? If so, find it.

Note: does not do any recursion – only looks at the top level.

Definition at line 1249 of file FOF.cpp.

1249 {
1250 size_t s = sub_formulas.size();
1251 for (size_t i = 0; i < s; i++) {
1252 if (sub_formulas[i].type == FOFType::Or) {
1253 return i;
1254 }
1255 }
1256 return s;
1257}

◆ fof_type()

FOFType FOF::fof_type ( )
inline

Basic get method.

Definition at line 268 of file FOF.hpp.

268{ return type; }

◆ has_free_variable()

bool FOF::has_free_variable ( Variable * v)
private

Does this formula contain the specified variable unbound?

Only use this if bound variables are unique. (If it finds any quantifier binding the variable it will return false.)

Parameters
vPointer to Variable of interest.

Definition at line 36 of file FOF.cpp.

36 {
37 switch (type) {
38 case FOFType::Empty:
39 cerr << "Don't do this with an Empty FOF!" << endl;
40 return false;
41 break;
42 case FOFType::Atom:
43 return pred.contains_variable(v);
44 case FOFType::Neg:
45 return (sub_formulas[0].has_free_variable(v));
46 break;
47 case FOFType::And:
48 case FOFType::Or:
49 for (size_t i = 0; i < sub_formulas.size(); i++) {
51 return true;
52 }
53 }
54 return false;
55 break;
56 case FOFType::Imp:
57 case FOFType::Iff:
58 return (sub_formulas[0].has_free_variable(v) ||
60 break;
61 case FOFType::A:
62 case FOFType::E:
63 if (var == v)
64 return false;
65 return sub_formulas[0].has_free_variable(v);
66 break;
67 default:
68 break;
69 }
70 return false;
71}
bool has_free_variable(Variable *)
Does this formula contain the specified variable unbound?
Definition FOF.cpp:36
bool contains_variable(Variable *) const
Does this Literal contain the specified variable?
Definition Literal.cpp:131

◆ invert_literal()

void FOF::invert_literal ( )

Self-explanatory!

Definition at line 462 of file FOF.cpp.

462 {
463 if (type == FOFType::Atom) {
465 return;
466 }
467 if (type == FOFType::Neg && sub_formulas[0].type == FOFType::Atom) {
469 return;
470 }
471 cerr << "Don't use this with a non-literal." << endl;
472}
void remove_negation()
Remove the leading negation from an arbitrary FOF, if it has one.
Definition FOF.cpp:424

◆ is_clause()

bool FOF::is_clause ( ) const

Check if something is a clause.

This checks in the strict sense: either it must be a literal or a disjunction of literals, including an empty disjunction.

Returns false if FOFType::Empty.

Definition at line 407 of file FOF.cpp.

407 {
408 if (is_literal()) {
409 return true;
410 }
411 if (!(type == FOFType::Or)) {
412 return false;
413 }
414 for (size_t i = 0; i < sub_formulas.size(); i++) {
415 if (!sub_formulas[i].is_literal()) {
416 return false;
417 }
418 }
419 return true;
420}

◆ is_literal()

bool FOF::is_literal ( ) const

Check if an FOF is a literal.

Works in general, not just for NNF.

Definition at line 402 of file FOF.cpp.

402 {
403 return (type == FOFType::Atom) ||
404 (type == FOFType::Neg && sub_formulas[0].type == FOFType::Atom);
405}

◆ make_and()

static FOF FOF::make_and ( const vector< FOF > & fs)
inlinestatic

Directly make a conjunction.

Definition at line 306 of file FOF.hpp.

306 {
307 FOF result(FOFType::And, fs, nullptr);
308 return result;
309 }

◆ make_definitional_predicate()

FOF FOF::make_definitional_predicate ( ) const
private

When doing definitional clause conversion you need to be able to make unique new predicates. This will provide one.

Definition at line 87 of file FOF.cpp.

87 {
88 set<Term*> a = this->find_free_variables();
89 vector<Term*> args;
90 for (Term* p : a)
91 args.push_back(p);
93 Literal lit(name, args, args.size(), true);
94 return FOF(lit);
95}
set< Term * > find_free_variables() const
Find the free variables in the formula.
Definition FOF.cpp:1511
static PredicateIndex * pred_index
Access to the index: static because all FOFs should share it.
Definition FOF.hpp:100
Basic representation of predicates: here just names, ids and arities.
Definition Predicate.hpp:51
Predicate * make_definitional_predicate(Arity arity)
Make a new, unique definitional predicate.

◆ make_exists()

static FOF FOF::make_exists ( const FOF & f,
Variable * v )
inlinestatic

Directly make an existentially quantified FOF.

Definition at line 349 of file FOF.hpp.

349 {
350 vector<FOF> fs;
351 fs.push_back(f);
352 FOF result(FOFType::E, fs, v);
353 return result;
354 }

◆ make_forall()

static FOF FOF::make_forall ( const FOF & f,
Variable * v )
inlinestatic

Directly make a universally quantified FOF.

Definition at line 340 of file FOF.hpp.

340 {
341 vector<FOF> fs;
342 fs.push_back(f);
343 FOF result(FOFType::A, fs, v);
344 return result;
345 }

◆ make_iff()

static FOF FOF::make_iff ( const FOF & lhs,
const FOF & rhs )
inlinestatic

Directly make an iff.

Definition at line 330 of file FOF.hpp.

330 {
331 vector<FOF> fs;
332 fs.push_back(lhs);
333 fs.push_back(rhs);
334 FOF result(FOFType::Iff, fs, nullptr);
335 return result;
336 }

◆ make_imp()

static FOF FOF::make_imp ( const FOF & lhs,
const FOF & rhs )
inlinestatic

Directly make an implication.

Definition at line 320 of file FOF.hpp.

320 {
321 vector<FOF> fs;
322 fs.push_back(lhs);
323 fs.push_back(rhs);
324 FOF result(FOFType::Imp, fs, nullptr);
325 return result;
326 }

◆ make_literal()

static FOF FOF::make_literal ( const Literal & lit)
inlinestatic

Directly make a Literal.

Definition at line 288 of file FOF.hpp.

288 {
289 FOF result(lit);
290 return result;
291 }

◆ make_neg()

static FOF FOF::make_neg ( const FOF & f)
inlinestatic

Directly negate a FOF.

Careful: no attempt here to make any obvious simplifications.

Definition at line 297 of file FOF.hpp.

297 {
298 vector<FOF> fs;
299 fs.push_back(f);
300 FOF result(FOFType::Neg, fs, nullptr);
301 return result;
302 }

◆ make_or()

static FOF FOF::make_or ( const vector< FOF > & fs)
inlinestatic

Directly make a disjunction.

Definition at line 313 of file FOF.hpp.

313 {
314 FOF result(FOFType::Or, fs, nullptr);
315 return result;
316 }

◆ make_skolem_function()

Term * FOF::make_skolem_function ( const vector< Term * > & args)
private

Make a new Skolem function.

Mainly achieved using methods from other classes.

Parameters
argsVector of pointers to Term. These are the Skolem function arguments.

Definition at line 205 of file FOF.cpp.

205 {
206 Function* sk = fun_index->make_skolem_function(args.size());
207 Term* sk_t = term_index->add_function_term(sk, args);
208 return sk_t;
209}
static FunctionIndex * fun_index
Access to the index: static because all FOFs should share it.
Definition FOF.hpp:90
Basic representation of functions.
Definition Function.hpp:54
Function * make_skolem_function(Arity)
Add a new Skolem function. Naming is automatic.
Term * add_function_term(Function *, const vector< Term * > &)
Self-explanatory: add a Term containing a function to the index.
Definition TermIndex.cpp:56

◆ make_unique_bound_variables()

void FOF::make_unique_bound_variables ( )

Replace all bound variables with unique new ones.

Has to be done with care to maintain the indexes correctly.

Definition at line 519 of file FOF.cpp.

519 {
520 Variable* new_var;
521 switch (type) {
522 case FOFType::Atom:
523 break;
524 case FOFType::Neg:
525 case FOFType::And:
526 case FOFType::Or:
527 case FOFType::Imp:
528 case FOFType::Iff:
529 for (FOF& sf : sub_formulas)
530 sf.make_unique_bound_variables();
531 break;
532 case FOFType::A:
533 case FOFType::E:
534 sub_formulas[0].make_unique_bound_variables();
535 new_var = var_index->add_unique_var();
536 sub_formulas[0].replace_variable(new_var, var);
537 var = new_var;
538 break;
539 default:
540 break;
541 }
542}
static VariableIndex * var_index
Access to the index: static because all FOFs should share it.
Definition FOF.hpp:85
Basic representation of variables.
Definition Variable.hpp:58
Variable * add_unique_var()
Add a unique variable when converting to CNF.

◆ miniscope()

void FOF::miniscope ( )

Apply the rules for miniscoping.

Push the quantifiers in as much as you can. Don't use this unless your formula is in NNF.

Definition at line 648 of file FOF.cpp.

648 {
649 vector<FOF> free;
650 vector<FOF> absent;
651 FOF new_sub(FOFType::Empty);
652 vector<FOF> new_subs;
653 Variable* new_var;
654 switch (type) {
655 case FOFType::Empty:
656 cerr << "Don't do this with an empty formula" << endl;
657 break;
658 case FOFType::Atom:
659 case FOFType::Neg:
660 break;
661 case FOFType::And:
662 case FOFType::Or:
664 break;
665 case FOFType::Imp:
666 case FOFType::Iff:
667 cerr << "Don't do this unless you've removed -> and <->" << endl;
668 break;
669 // Remember you're only dealing with stuff in NNF. You
670 // do however have to handle nested quantifiers.
671 case FOFType::A:
672 sub_formulas[0].miniscope();
673 if (!(sub_formulas[0].type == FOFType::And ||
674 sub_formulas[0].type == FOFType::Or)) {
675 return;
676 }
677 // You have \forall followed by (miniscoped) AND or OR.
678 miniscope_split(var, free, absent);
679 // If the quantifier is followed by AND you can just
680 // make a \forall for every subformula involving the
681 // variable.
682 if (sub_formulas[0].type == FOFType::And) {
683 type = FOFType::And;
684 // If everything is bound then make a new forall everywhere
685 // with a new variable.
686 if (free.size() == sub_formulas[0].sub_formulas.size()) {
687 for (size_t i = 0; i < free.size(); i++) {
688 new_var = var_index->add_unique_var();
689 new_sub = free[i];
690 new_sub.replace_variable(new_var, var);
691 new_sub = FOF::make_forall(new_sub, new_var);
692 new_subs.push_back(new_sub);
693 }
694 sub_formulas = new_subs;
695 }
696 // If any subformula doesn't have the variable then just
697 // move the forall in. Remember you need to consider the
698 // possibility that the quantifier can just be removed.
699 else if (free.size() > 0) {
700 sub_formulas = absent;
701 if (free.size() == 1)
702 new_sub = free[0];
703 else
704 new_sub = FOF::make_and(free);
705 new_sub = FOF::make_forall(new_sub, var);
706 sub_formulas.push_back(new_sub);
707 }
708 // You're just going to remove the quantifier.
709 else {
710 sub_formulas = sub_formulas[0].sub_formulas;
711 }
712 var = nullptr;
714 return;
715 }
716 if (sub_formulas[0].type == FOFType::Or) {
717 // You have a \forall followed by an OR.
718 // If eveything is bound there's nothing to do.
719 if (absent.size() == 0)
720 return;
721 else if (free.size() > 0) {
722 type = FOFType::Or;
723 sub_formulas = absent;
724 if (free.size() == 1)
725 new_sub = free[0];
726 else
727 new_sub = FOF::make_or(free);
728 new_sub = FOF::make_forall(new_sub, var);
729 sub_formulas.push_back(new_sub);
730 var = nullptr;
732 }
733 // You can just drop the quantifier.
734 else {
735 type = FOFType::Or;
736 vector<FOF> sf(sub_formulas);
737 sub_formulas = sf[0].sub_formulas;
738 var = nullptr;
739 }
740 return;
741 }
742 break;
743 // You have an \exists.
744 case FOFType::E:
745 sub_formulas[0].miniscope();
746 if (!(sub_formulas[0].type == FOFType::And ||
747 sub_formulas[0].type == FOFType::Or)) {
748 return;
749 }
750 // You have an \exists followed by AND or OR.
751 miniscope_split(var, free, absent);
752 if (sub_formulas[0].type == FOFType::Or) {
753 type = FOFType::Or;
754 // If everything is bound then make a new exists everywhere
755 // with a new variable.
756 if (free.size() == sub_formulas[0].sub_formulas.size()) {
757 for (size_t i = 0; i < free.size(); i++) {
758 new_var = var_index->add_unique_var();
759 new_sub = free[i];
760 new_sub.replace_variable(new_var, var);
761 new_sub = FOF::make_exists(new_sub, new_var);
762 new_subs.push_back(new_sub);
763 }
764 sub_formulas = new_subs;
765 }
766 // If any subformula doesn't have the variable then just
767 // move the \exists in.
768 else if (free.size() > 0) {
769 sub_formulas = absent;
770 if (free.size() == 1)
771 new_sub = free[0];
772 else
773 new_sub = FOF::make_or(free);
774 new_sub = FOF::make_exists(new_sub, var);
775 sub_formulas.push_back(new_sub);
776 }
777 // We're just going to drop the quantifier.
778 else {
779 sub_formulas = sub_formulas[0].sub_formulas;
780 }
781 var = nullptr;
783 return;
784 }
785 // You have an \exists followed by and AND.
786 if (sub_formulas[0].type == FOFType::And) {
787 // If eveything is bound there's nothing to do.
788 if (absent.size() == 0)
789 return;
790 else if (free.size() != sub_formulas[0].sub_formulas.size()) {
791 type = FOFType::And;
792 sub_formulas = absent;
793 if (free.size() == 1)
794 new_sub = free[0];
795 else
796 new_sub = FOF::make_and(free);
797 new_sub = FOF::make_exists(new_sub, var);
798 sub_formulas.push_back(new_sub);
799 var = nullptr;
801 }
802 // We can just drop the quantifier.
803 else {
804 type = FOFType::And;
805 vector<FOF> sf(sub_formulas);
806 sub_formulas = sf[0].sub_formulas;
807 var = nullptr;
808 }
809 return;
810 }
811 break;
812 default:
813 break;
814 }
815}
void miniscope_all()
Apply miniscoping to all subformulas.
Definition FOF.cpp:339
void miniscope_split(Variable *, vector< FOF > &, vector< FOF > &)
Helper for miniscope.
Definition FOF.cpp:323
static FOF make_exists(const FOF &f, Variable *v)
Directly make an existentially quantified FOF.
Definition FOF.hpp:349
static FOF make_forall(const FOF &f, Variable *v)
Directly make a universally quantified FOF.
Definition FOF.hpp:340

◆ miniscope_all()

void FOF::miniscope_all ( )
private

Apply miniscoping to all subformulas.

Definition at line 339 of file FOF.cpp.

339 {
340 for (size_t i = 0; i < sub_formulas.size(); i++ ) {
341 sub_formulas[i].miniscope();
342 }
343}

◆ miniscope_split()

void FOF::miniscope_split ( Variable * v,
vector< FOF > & free,
vector< FOF > & absent )
private

Helper for miniscope.

Split subformulas into ones that do and don't have the relevant variable.

Parameters
vPointer to Variable of interest.
freeReference to vector of FOF. Collect FOFs with the Variable.
absentReference to vector of FOF. Collect FOFs without the Variable.

Definition at line 323 of file FOF.cpp.

325 {
326 // Remember that at this point you have a NNF with
327 // unique variables. So whatever is in the subformula
328 // is AND, OR, Atom or Neg (Literal).
329 vector<FOF>& subs = sub_formulas[0].sub_formulas;
330 for (size_t i = 0; i < subs.size(); i++) {
331 FOF f(subs[i]);
332 if (f.has_free_variable(v))
333 free.push_back(f);
334 else
335 absent.push_back(f);
336 }
337}

◆ negate()

void FOF::negate ( )

Negate an FOF, applying obvious simplifications if it's already negated or an implication.

Definition at line 431 of file FOF.cpp.

431 {
432 if (type == FOFType::Empty) {
433 cerr << "Don't do this with an Empty FOF!" << endl;
434 return;
435 }
436 if (type == FOFType::Imp) {
437 type = FOFType::And;
438 sub_formulas[1].negate();
439 }
440 else if (type == FOFType::Neg) {
442 }
443 else {
444 FOF f = *this;
445 type = FOFType::Neg;
446 pred.clear();
447 var = nullptr;
448 sub_formulas.clear();
449 sub_formulas.push_back(f);
450 }
451}

◆ predicate_to_tptp_string()

string FOF::predicate_to_tptp_string ( ) const

Assuming this is an Atom, return the predicate name as a string.

Definition at line 1438 of file FOF.cpp.

1438 {
1439 if (type != FOFType::Atom) {
1440 cerr << "You should only be doing this with an atom!" << endl;
1441 return string();
1442 }
1443 return pred.get_pred()->to_tptp_string();
1444
1445}
Predicate * get_pred() const
Basic get method.
Definition Literal.hpp:71
string to_tptp_string() const
At present returns only the name.
Definition Predicate.cpp:32

◆ push_negs()

void FOF::push_negs ( )

Push all negations in.

DON'T call it on anything with a -> or <->.

Definition at line 573 of file FOF.cpp.

573 {
574 switch (type) {
575 case FOFType::Neg:
576 switch (sub_formulas[0].type) {
577 case FOFType::Neg:
580 push_negs();
581 break;
582 case FOFType::Atom:
583 break;
584 case FOFType::And:
586 type = FOFType::Or;
587 for (FOF& f : sub_formulas) {
588 f.negate();
589 f.push_negs();
590 }
591 break;
592 case FOFType::Or:
594 type = FOFType::And;
595 for (FOF& f : sub_formulas) {
596 f.negate();
597 f.push_negs();
598 }
599 break;
600 case FOFType::A:
602 type = FOFType::E;
603 sub_formulas[0].negate();
604 sub_formulas[0].push_negs();
605 break;
606 case FOFType::E:
608 type = FOFType::A;
609 sub_formulas[0].negate();
610 sub_formulas[0].push_negs();
611 break;
612 case FOFType::Imp:
613 case FOFType::Iff:
614 cerr << "Stop it!!! You don't push negations through -> or <->." << endl;
615 break;
616 default:
617 break;
618 }
619 break;
620 case FOFType::Atom:
621 break;
622 case FOFType::And:
623 case FOFType::Or:
624 case FOFType::A:
625 case FOFType::E:
626 for (FOF& f : sub_formulas)
627 f.push_negs();
628 break;
629 case FOFType::Imp:
630 case FOFType::Iff:
631 cerr << "Stop it!!! You don't push negations through -> or <->." << endl;
632 break;
633 default:
634 break;
635 }
636}

◆ remove_existential_quantifiers()

void FOF::remove_existential_quantifiers ( )

Self-explanatory.

Definition at line 1131 of file FOF.cpp.

1131 {
1132 FOF f(FOFType::Atom);
1133 switch (type) {
1134 case FOFType::Atom:
1135 break;
1136 case FOFType::Neg:
1137 sub_formulas[0].remove_existential_quantifiers();
1138 break;
1139 case FOFType::And:
1140 case FOFType::Or:
1141 case FOFType::Imp:
1142 case FOFType::Iff:
1143 for (FOF& g : sub_formulas)
1144 g.remove_existential_quantifiers();
1145 break;
1146 case FOFType::E:
1147 sub_formulas[0].remove_existential_quantifiers();
1148 f = sub_formulas[0];
1149 *this = f;
1150 break;
1151 case FOFType::A:
1152 sub_formulas[0].remove_existential_quantifiers();
1153 break;
1154 default:
1155 break;
1156 }
1157}

◆ remove_iff()

void FOF::remove_iff ( )

Replace <-> throughout using ->.

Definition at line 474 of file FOF.cpp.

474 {
475 if (type == FOFType::Empty) {
476 cerr << "Don't do this with an Empty FOF!" << endl;
477 return;
478 }
479 // End of recursion.
480 if (type == FOFType::Atom)
481 return;
482 // Do the relevant transformation.
483 if (type == FOFType::Iff) {
484 FOF lhs = *this;
485 FOF rhs = *this;
486 lhs.type = FOFType::Imp;
487 rhs.type = FOFType::Imp;
488 FOF store = rhs.sub_formulas[1];
489 rhs.sub_formulas[1] = rhs.sub_formulas[0];
490 rhs.sub_formulas[0] = store;
491 type = FOFType::And;
492 sub_formulas.clear();
493 sub_formulas.push_back(lhs);
494 sub_formulas.push_back(rhs);
495 }
496 // Finish the job. Also applies the transformation to other FOF types.
497 for (FOF& f : sub_formulas)
498 f.remove_iff();
499}

◆ remove_imp()

void FOF::remove_imp ( )

Replace A->B throughout with neg A v B.

Definition at line 501 of file FOF.cpp.

501 {
502 if (type == FOFType::Empty) {
503 cerr << "Don't do this with an Empty FOF!" << endl;
504 return;
505 }
506 // End of recursion.
507 if (type == FOFType::Atom)
508 return;
509 // Do the relevant transformation.
510 if (type == FOFType::Imp) {
511 type = FOFType::Or;
512 sub_formulas[0].negate();
513 }
514 // Finish the job. Also applies the transformation to other FOF types.
515 for (FOF& f : sub_formulas)
516 f.remove_imp();
517}

◆ remove_negation()

void FOF::remove_negation ( )

Remove the leading negation from an arbitrary FOF, if it has one.

Definition at line 424 of file FOF.cpp.

424 {
425 if (type == FOFType::Neg) {
426 FOF f = sub_formulas[0];
427 *this = f;
428 }
429}

◆ remove_redundant_quantifiers()

void FOF::remove_redundant_quantifiers ( )

Remove quantifiers if they don't bind anything in their scope.

Yes, the TPTP does contain such formulas. Use this only if bound variables are unique.

Definition at line 544 of file FOF.cpp.

544 {
545 Variable* new_var;
546 switch (type) {
547 case FOFType::Atom:
548 break;
549 case FOFType::Neg:
550 case FOFType::And:
551 case FOFType::Or:
552 case FOFType::Imp:
553 case FOFType::Iff:
554 for (FOF& sf : sub_formulas)
555 sf.remove_redundant_quantifiers();
556 break;
557 case FOFType::A:
558 case FOFType::E:
559 sub_formulas[0].remove_redundant_quantifiers();
561 vector<FOF> sf(sub_formulas);
562 type = sub_formulas[0].type;
563 pred = sub_formulas[0].pred;
564 var = sub_formulas[0].var;
565 sub_formulas = sf[0].sub_formulas;
566 }
567 break;
568 default:
569 break;
570 }
571}

◆ remove_universal_quantifiers()

void FOF::remove_universal_quantifiers ( )

Self-explanatory.

Definition at line 1103 of file FOF.cpp.

1103 {
1104 FOF f(FOFType::Atom);
1105 switch (type) {
1106 case FOFType::Atom:
1107 break;
1108 case FOFType::Neg:
1109 sub_formulas[0].remove_universal_quantifiers();
1110 break;
1111 case FOFType::And:
1112 case FOFType::Or:
1113 case FOFType::Imp:
1114 case FOFType::Iff:
1115 for (FOF& g : sub_formulas)
1116 g.remove_universal_quantifiers();
1117 break;
1118 case FOFType::A:
1119 sub_formulas[0].remove_universal_quantifiers();
1120 f = sub_formulas[0];
1121 *this = f;
1122 break;
1123 case FOFType::E:
1124 sub_formulas[0].remove_universal_quantifiers();
1125 break;
1126 default:
1127 break;
1128 }
1129}

◆ replace_variable()

void FOF::replace_variable ( Variable * new_var,
Variable * old_var )
private

Self-explanatory.

However note that this works only on Atoms: quantifiers will be unaffected.

Parameters
new_varPointer to new Variable.
old_varPointer to Variable to replace.

Definition at line 73 of file FOF.cpp.

73 {
74 if (type == FOFType::Empty) {
75 cerr << "Don't do this with an Empty FOF!" << endl;
76 return;
77 }
78 if (type == FOFType::Atom) {
79 pred.replace_variable(new_var, old_var, term_index);
80 }
81 else {
82 for (FOF& f : sub_formulas)
83 f.replace_variable(new_var, old_var);
84 }
85}
void replace_variable(Variable *, Variable *, TermIndex *)
Replace one variable with another throughout.
Definition Literal.cpp:287

◆ replace_variable_with_term()

void FOF::replace_variable_with_term ( Term * new_term,
Variable * old_var )
private

Replace a Variable with a Term.

Mainly achieved using methods from other classes.

Note that this works only on Atoms: quantifiers will be unaffected.

Parameters
new_termPointer to new Term to use.
old_varPointer to Variable to replace.

Definition at line 211 of file FOF.cpp.

211 {
212 if (type == FOFType::Empty) {
213 cerr << "Don't do this with an Empty FOF!" << endl;
214 return;
215 }
216 if (type == FOFType::Atom) {
217 pred.replace_variable_with_term(new_term, old_var, term_index);
218 }
219 else {
220 for (FOF& f : sub_formulas)
221 f.replace_variable_with_term(new_term, old_var);
222 }
223}
void replace_variable_with_term(Term *, Variable *, TermIndex *)
Replace one variable with a term throughout.
Definition Literal.cpp:298

◆ set_indexes()

static void FOF::set_indexes ( std::tuple< VariableIndex *, FunctionIndex *, PredicateIndex *, TermIndex * > is)
inlinestatic

Set up pointer to the variable index etc.

Definition at line 241 of file FOF.hpp.

244 {
245 var_index = std::get<0>(is);
246 fun_index = std::get<1>(is);
247 pred_index = std::get<2>(is);
248 term_index = std::get<3>(is);
249 }

◆ set_recs_p()

static void FOF::set_recs_p ( TPTPRecords * _p)
inlinestatic

Set up the pointer allowing TPTP outputs to be added.

Definition at line 253 of file FOF.hpp.

253 {
254 recs_p = _p;
255 }

◆ show_indexes()

void FOF::show_indexes ( ) const
inline

Show the indices.

Definition at line 259 of file FOF.hpp.

259 {
260 cout << var_index << " " << fun_index
261 << " " << pred_index
262 << " " << term_index
263 << endl;
264 }

◆ simple_negate()

void FOF::simple_negate ( )

Negate an FOF without applying any simplifications.

Definition at line 453 of file FOF.cpp.

453 {
454 FOF f = *this;
455 type = FOFType::Neg;
456 pred.clear();
457 var = nullptr;
458 sub_formulas.clear();
459 sub_formulas.push_back(f);
460}

◆ simplify_cnf() [1/2]

SimplificationResult FOF::simplify_cnf ( vector< Clause > & cnf)
static

Simplify the clauses in a CNF using the method in Clause.

Definition at line 1490 of file FOF.cpp.

1490 {
1491 vector<Clause> new_cnf;
1492 bool cnf_is_contradiction = false;
1493 for (Clause& c : cnf) {
1494 SimplificationResult result = c.simplify();
1495 if (result == SimplificationResult::Tautology)
1496 continue;
1497 if (result == SimplificationResult::Contradiction) {
1498 cnf_is_contradiction = true;
1499 continue;
1500 }
1501 new_cnf.push_back(c);
1502 }
1503 cnf = new_cnf;
1504 if (cnf_is_contradiction)
1505 return SimplificationResult::Contradiction;
1506 if (cnf.size() == 0)
1507 return SimplificationResult::Tautology;
1508 return SimplificationResult::OK;
1509}

◆ simplify_cnf() [2/2]

SimplificationResult FOF::simplify_cnf ( vector< Clause > & cnf,
vector< string > & roles,
vector< string > & names )
static

As first version of simplify_cnf, but keep track of corresponding roles as well.

Definition at line 1447 of file FOF.cpp.

1449 {
1450 vector<Clause> new_cnf;
1451 vector<string> new_roles;
1452 vector<string> new_names;
1453 bool cnf_is_contradiction = false;
1454 size_t i = 0;
1455 for (Clause& c : cnf) {
1456 Clause c2 = c;
1457 SimplificationResult result = c.simplify();
1458 if (result == SimplificationResult::Tautology) {
1459 recs_p->add_tf_clause_record(names[i], roles[i], "$true");
1460 i++;
1461 continue;
1462 }
1463 if (result == SimplificationResult::Contradiction) {
1464 cnf_is_contradiction = true;
1465 recs_p->add_tf_clause_record(names[i], roles[i], "$false");
1466 i++;
1467 continue;
1468 }
1469 new_cnf.push_back(c);
1470 new_roles.push_back(roles[i]);
1471 if (c == c2) {
1472 new_names.push_back(names[i]);
1473 }
1474 else {
1475 string new_name = recs_p->add_clause_record(c, roles[i], names[i]);
1476 new_names.push_back(new_name);
1477 }
1478 i++;
1479 }
1480 cnf = new_cnf;
1481 roles = new_roles;
1482 names = new_names;
1483 if (cnf_is_contradiction)
1484 return SimplificationResult::Contradiction;
1485 if (cnf.size() == 0)
1486 return SimplificationResult::Tautology;
1487 return SimplificationResult::OK;
1488}
SimplificationResult simplify()
Simplify a clause by dealing with $true, $false, complementary literals, and duplicates.
Definition Clause.cpp:143

◆ skolemize()

void FOF::skolemize ( )

Skolemize the given formula.

All the hard work is done by skolemize_main.

See also
skolemize_main

Definition at line 1093 of file FOF.cpp.

1093 {
1094 vector<Term*> skolem_arguments;
1095 skolemize_main(skolem_arguments, this, true);
1096}
void skolemize_main(vector< Term * >, FOF *, bool=false)
Main helper function called by FOF::skolemize().
Definition FOF.cpp:225

◆ skolemize_main()

void FOF::skolemize_main ( vector< Term * > skolem_arguments,
FOF * whole_f,
bool tptp = false )
private

Main helper function called by FOF::skolemize().

The parameter is used to collect variables for the universal quantifiers inside which you find an existential quantifier. Those then become the parameters for the Skolem function.

Parameters
skolem_argumentsVector of pointers to Term.
See also
make_skolem_function.
replace_variable_with_term.

Definition at line 225 of file FOF.cpp.

227 {
228 Term* sk_t;
229 FOF f(FOFType::Atom);
230 string sk_s;
231 string sk_t_s;
232 string var_s;
233 string f_s;
234 switch (type) {
235 case FOFType::Atom:
236 break;
237 case FOFType::Neg:
238 sub_formulas[0].skolemize_main(skolem_arguments, whole_f, tptp);
239 break;
240 case FOFType::And:
241 case FOFType::Or:
242 case FOFType::Imp:
243 case FOFType::Iff:
244 for (FOF& g : sub_formulas)
245 g.skolemize_main(skolem_arguments, whole_f, tptp);
246 break;
247 case FOFType::A:
248 skolem_arguments.push_back(term_index->add_variable_term(var));
249 sub_formulas[0].skolemize_main(skolem_arguments, whole_f, tptp);
250 break;
251 case FOFType::E:
252 sk_t = make_skolem_function(skolem_arguments);
253 if (tptp) {
254 sk_s = sk_t->get_f()->get_name();
255 sk_t_s = sk_t->to_prolog_string();
256 var_s = var->to_prolog_string();
257 }
258 sub_formulas[0].replace_variable_with_term(sk_t, var);
259 f = sub_formulas[0];
260 *this = f;
261 if (tptp) {
262 FOF f2 = *whole_f;
263 f_s = f2.to_tptp_string();
264 recs_p->add_skolemization_record(f_s, var_s, sk_t_s, sk_s);
265 }
266 skolemize_main(skolem_arguments, whole_f, tptp);
267 break;
268 default:
269 break;
270 }
271}
Term * make_skolem_function(const vector< Term * > &)
Make a new Skolem function.
Definition FOF.cpp:205
string get_name() const
Most basic access function.
Definition Function.hpp:84
Function * get_f() const
Self-explanatory access function.
Definition Term.hpp:90
string to_prolog_string(bool=false) const
Convert to a string that can be read by Prolog.
Definition Term.cpp:202
string to_prolog_string(bool=false) const
Convert to a Prolog string.
Definition Term.cpp:346

◆ skolemize_universals()

void FOF::skolemize_universals ( )

Skolemize the universal quantifiers in the given formula.

All the hard work is done by skolemize_universals_main.

See also
skolemize_universals_main

Definition at line 1098 of file FOF.cpp.

1098 {
1099 vector<Term*> skolem_arguments;
1100 skolemize_universals_main(skolem_arguments, this, true);
1101}
void skolemize_universals_main(vector< Term * >, FOF *, bool=false)
The dual of skolemize_main.
Definition FOF.cpp:273

◆ skolemize_universals_main()

void FOF::skolemize_universals_main ( vector< Term * > skolem_arguments,
FOF * whole_f,
bool tptp = false )
private

The dual of skolemize_main.

See also
skolemize_main

Definition at line 273 of file FOF.cpp.

275 {
276 Term* sk_t;
277 FOF f(FOFType::Atom);
278 string sk_s;
279 string sk_t_s;
280 string var_s;
281 string f_s;
282 switch (type) {
283 case FOFType::Atom:
284 break;
285 case FOFType::Neg:
286 sub_formulas[0].skolemize_universals_main(skolem_arguments, whole_f, tptp);
287 break;
288 case FOFType::And:
289 case FOFType::Or:
290 case FOFType::Imp:
291 case FOFType::Iff:
292 for (FOF& g : sub_formulas)
293 g.skolemize_universals_main(skolem_arguments, whole_f, tptp);
294 break;
295 case FOFType::E:
296 skolem_arguments.push_back(term_index->add_variable_term(var));
297 sub_formulas[0].skolemize_universals_main(skolem_arguments, whole_f, tptp);
298 break;
299 case FOFType::A:
300 sk_t = make_skolem_function(skolem_arguments);
301 if (tptp) {
302 sk_s = sk_t->get_f()->get_name();
303 sk_t_s = sk_t->to_prolog_string();
304 var_s = var->to_prolog_string();
305 }
306 sub_formulas[0].replace_variable_with_term(sk_t, var);
307 f = sub_formulas[0];
308 *this = f;
309 if (tptp) {
310 FOF f2 = *whole_f;
311 f_s = f2.to_tptp_string();
312 recs_p->add_herbrandization_record(f_s, var_s, sk_t_s, sk_s);
313 }
314 skolemize_universals_main(skolem_arguments, whole_f, tptp);
315 break;
316 default:
317 break;
318 }
319}

◆ split_sub_formulas()

void FOF::split_sub_formulas ( vector< FOF > & left_sub,
vector< FOF > & right_sub )

Split subformulas in half.

Parameters
left_subFirst half of the subformulas.
right_subSecond half of subformulas.

Definition at line 892 of file FOF.cpp.

892 {
893 left_sub.clear();
894 right_sub.clear();
895 size_t s = sub_formulas.size();
896 if (s == 2) {
897 left_sub.push_back(sub_formulas[0]);
898 right_sub.push_back(sub_formulas[1]);
899 return;
900 }
901 if (s == 3) {
902 right_sub.push_back(sub_formulas[2]);
903 left_sub = sub_formulas;
904 left_sub.pop_back();
905 return;
906 }
907 size_t left_size = s / 2;
908 for (size_t i = 0; i < left_size; i++) {
909 left_sub.push_back(sub_formulas[i]);
910 }
911 for (size_t i = left_size; i < s; i++) {
912 right_sub.push_back(sub_formulas[i]);
913 }
914}

◆ to_Literal()

void FOF::to_Literal ( Literal & new_lit) const

Assuming the FOF is a literal, convert it to something of type Literal.

This is straightforward as most of the heavy lifting has already been done. DON'T use it on an FOF that isn't in the form of a literal.

Definition at line 1159 of file FOF.cpp.

1159 {
1160 if (type == FOFType::Atom) {
1161 new_lit = pred;
1162 }
1163 else {
1164 new_lit = sub_formulas[0].pred;
1165 new_lit.make_negative();
1166 }
1167}
void make_negative()
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:103

◆ to_string()

string FOF::to_string ( ) const

Convert a FOF into a nice-looking string.

Definition at line 1267 of file FOF.cpp.

1267 {
1268 string result;
1269 size_t s = sub_formulas.size();;
1270 size_t i = 1;
1271 switch (type) {
1272 case FOFType::Atom:
1273 result = pred.to_string();
1274 break;
1275 case FOFType::Neg:
1276 result = unicode_symbols::LogSym::neg;
1277 result += "( ";
1278 result += sub_formulas[0].to_string();
1279 result += " )";
1280 break;
1281 case FOFType::And:
1282 result = "( ";
1283 for (const FOF& g : sub_formulas) {
1284 result += g.to_string();
1285 if (i < s) {
1286 result += " ";
1287 result += unicode_symbols::LogSym::and_sym;
1288 result += " ";
1289 }
1290 i++;
1291 }
1292 result += " )";
1293 break;
1294 case FOFType::Or:
1295 result = "( ";
1296 for (const FOF& g : sub_formulas) {
1297 result += g.to_string();
1298 if (i < s) {
1299 result += " ";
1300 result += unicode_symbols::LogSym::or_sym;
1301 result += " ";
1302 }
1303 i++;
1304 }
1305 result += " )";
1306 break;
1307 case FOFType::Imp:
1308 result = "( ";
1309 result += sub_formulas[0].to_string();
1310 result += " ";
1311 result += unicode_symbols::LogSym::ifthen;
1312 result += " ";
1313 result += sub_formulas[1].to_string();
1314 result += " )";
1315 break;
1316 case FOFType::Iff:
1317 result = "( ";
1318 result += sub_formulas[0].to_string();
1319 result += " ";
1320 result += unicode_symbols::LogSym::iff;
1321 result += " ";
1322 result += sub_formulas[1].to_string();
1323 result += " )";
1324 break;
1325 case FOFType::A:
1326 result = unicode_symbols::LogSym::forall;
1327 result += var->to_string();
1328 result += " . [ ";
1329 result += sub_formulas[0].to_string();
1330 result += " ]";
1331 break;
1332 case FOFType::E:
1333 result = unicode_symbols::LogSym::exists;
1334 result += var->to_string();
1335 result += " . [ ";
1336 result += sub_formulas[0].to_string();
1337 result += " ]";
1338 break;
1339 default:
1340 break;
1341 }
1342 return result;
1343}
string to_string(bool=false) const
Full conversion of Literal to string.
Definition Literal.cpp:185
string to_string(bool=false) const
Convert to a (coloured) string.
Definition Term.cpp:336

◆ to_tptp_string()

string FOF::to_tptp_string ( bool nesting = false) const

Convert a FOF into a nice-looking string in the TPTP format.

Argument allows you to collect variables for nested quantifiers.

Definition at line 1345 of file FOF.cpp.

1345 {
1346 string result;
1347 size_t s = sub_formulas.size();;
1348 size_t i = 1;
1349 bool nested = false;
1350 switch (type) {
1351 case FOFType::Atom:
1352 result = pred.to_tptp_string();
1353 break;
1354 case FOFType::Neg:
1355 result = "~";
1356 result += "( ";
1357 result += sub_formulas[0].to_tptp_string();
1358 result += " )";
1359 break;
1360 case FOFType::And:
1361 result = "( ";
1362 for (const FOF& g : sub_formulas) {
1363 result += g.to_tptp_string();
1364 if (i < s) {
1365 result += " ";
1366 result += "&";
1367 result += " ";
1368 }
1369 i++;
1370 }
1371 result += " )";
1372 break;
1373 case FOFType::Or:
1374 result = "( ";
1375 for (const FOF& g : sub_formulas) {
1376 result += g.to_tptp_string();
1377 if (i < s) {
1378 result += " ";
1379 result += "|";
1380 result += " ";
1381 }
1382 i++;
1383 }
1384 result += " )";
1385 break;
1386 case FOFType::Imp:
1387 result = "( ";
1388 result += sub_formulas[0].to_tptp_string();
1389 result += " ";
1390 result += "=>";
1391 result += " ";
1392 result += sub_formulas[1].to_tptp_string();
1393 result += " )";
1394 break;
1395 case FOFType::Iff:
1396 result = "( ";
1397 result += sub_formulas[0].to_tptp_string();
1398 result += " ";
1399 result += "<=>";
1400 result += " ";
1401 result += sub_formulas[1].to_tptp_string();
1402 result += " )";
1403 break;
1404 case FOFType::A:
1405 if (nesting) {
1406 result += ",";
1407 }
1408 else {
1409 result = "! [ ";
1410 }
1411 result += var->to_prolog_string();
1412 nested = sub_formulas[0].type == FOFType::A;
1413 if (!nested) {
1414 result += " ] : ";
1415 }
1416 result += sub_formulas[0].to_tptp_string(nested);
1417 break;
1418 case FOFType::E:
1419 if (nesting) {
1420 result += ",";
1421 }
1422 else {
1423 result = "? [ ";
1424 }
1425 result += var->to_prolog_string();
1426 nested = sub_formulas[0].type == FOFType::E;
1427 if (!nested) {
1428 result += " ] : ";
1429 }
1430 result += sub_formulas[0].to_tptp_string(nested);
1431 break;
1432 default:
1433 break;
1434 }
1435 return result;
1436}
string to_tptp_string(bool=false) const
Convert to a string in a format compatible with the TPTP.
Definition Literal.cpp:225

Friends And Related Symbol Documentation

◆ operator<<

ostream & operator<< ( ostream & out,
const FOF & f )
friend

Definition at line 1547 of file FOF.cpp.

1547 {
1548 out << f.to_string();
1549 return out;
1550}
string to_string() const
Convert a FOF into a nice-looking string.
Definition FOF.cpp:1267

Member Data Documentation

◆ fun_index

FunctionIndex * FOF::fun_index = nullptr
staticprivate

Access to the index: static because all FOFs should share it.

Definition at line 90 of file FOF.hpp.

◆ pred

Literal FOF::pred
private

FOFType::Atom can store one of these to represent a Literal.

Definition at line 72 of file FOF.hpp.

◆ pred_index

PredicateIndex * FOF::pred_index = nullptr
staticprivate

Access to the index: static because all FOFs should share it.

Definition at line 100 of file FOF.hpp.

◆ recs_p

TPTPRecords * FOF::recs_p = nullptr
staticprivate

Allow FOF to add TPTP outputs.

Definition at line 63 of file FOF.hpp.

◆ sub_formulas

vector<FOF> FOF::sub_formulas
private

Most FOFs will have subformulas.

Definition at line 76 of file FOF.hpp.

◆ term_index

TermIndex * FOF::term_index = nullptr
staticprivate

Access to the index: static because all FOFs should share it.

Definition at line 95 of file FOF.hpp.

◆ type

FOFType FOF::type
private

Used for all FOFs to denote what kind it it.

Definition at line 67 of file FOF.hpp.

◆ var

Variable* FOF::var
private

Associate a Variable with a quantifier.

Definition at line 80 of file FOF.hpp.

◆ var_index

VariableIndex * FOF::var_index = nullptr
staticprivate

Access to the index: static because all FOFs should share it.

Definition at line 85 of file FOF.hpp.


The documentation for this class was generated from the following files: