#ifndef __VampireAPI__
#define __VampireAPI__
#include <string>
#include <initializer_list>
#include <ostream>
#include <vector>
#include "Forwards.hpp"
#include "Kernel/Term.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/Formula.hpp"
#include "Kernel/FormulaUnit.hpp"
#include "Kernel/Problem.hpp"
#include "Kernel/Signature.hpp"
#include "Kernel/Inference.hpp"
#include "Shell/Options.hpp"
#include "Shell/Statistics.hpp"
namespace Api {
using namespace Kernel;
using namespace Shell;
enum class ProofResult {
PROOF, SATISFIABLE, TIMEOUT, MEMORY_LIMIT, UNKNOWN, INCOMPLETE };
void prepareForNextProof();
void reset();
Options& options();
Signature& signature();
Statistics& statistics();
unsigned addFunction(const std::string& name, unsigned arity);
unsigned addPredicate(const std::string& name, unsigned arity);
TermList var(unsigned index);
TermList constant(unsigned functor);
TermList term(unsigned functor, std::initializer_list<TermList> args);
TermList term(unsigned functor, const std::vector<TermList>& args);
Literal* eq(bool positive, TermList lhs, TermList rhs);
Literal* lit(unsigned pred, bool positive, std::initializer_list<TermList> args);
Literal* lit(unsigned pred, bool positive, const std::vector<TermList>& args);
Literal* neg(Literal* l);
Formula* atom(Literal* l);
Formula* notF(Formula* f);
Formula* andF(std::initializer_list<Formula*> fs);
Formula* andF(const std::vector<Formula*>& fs);
Formula* orF(std::initializer_list<Formula*> fs);
Formula* orF(const std::vector<Formula*>& fs);
Formula* impF(Formula* lhs, Formula* rhs);
Formula* iffF(Formula* lhs, Formula* rhs);
Formula* forallF(unsigned varIndex, Formula* f);
Formula* existsF(unsigned varIndex, Formula* f);
Formula* trueF();
Formula* falseF();
Unit* axiomF(Formula* f);
Unit* conjectureF(Formula* f);
Clause* axiom(std::initializer_list<Literal*> literals);
Clause* axiom(const std::vector<Literal*>& literals);
Clause* conjecture(std::initializer_list<Literal*> literals);
Clause* conjecture(const std::vector<Literal*>& literals);
Clause* clause(std::initializer_list<Literal*> literals, UnitInputType inputType);
Clause* clause(const std::vector<Literal*>& literals, UnitInputType inputType);
Problem* problem(std::initializer_list<Clause*> clauses);
Problem* problem(const std::vector<Clause*>& clauses);
Problem* problem(std::initializer_list<Unit*> units);
Problem* problem(const std::vector<Unit*>& units);
ProofResult prove(Problem* prb);
Unit* getRefutation();
void printProof(std::ostream& out, Unit* refutation);
struct ProofStep {
unsigned id; InferenceRule rule; UnitInputType inputType; std::vector<unsigned> premiseIds; Unit* unit;
Clause* clause() const;
bool isEmpty() const;
bool isInput() const { return premiseIds.empty(); }
std::string ruleName() const;
std::string inputTypeName() const;
};
std::vector<ProofStep> extractProof(Unit* refutation);
std::vector<Literal*> getLiterals(Clause* c);
std::string termToString(TermList t);
std::string literalToString(Literal* l);
std::string clauseToString(Clause* c);
std::string formulaToString(Formula* f);
}
#endif