#include <iostream>
#include "Api/VampireAPI.hpp"
using namespace Api;
using namespace Kernel;
int main() {
options().setTimeLimitInSeconds(10);
unsigned lt = addPredicate("lt", 2); unsigned a = addFunction("a", 0); unsigned b = addFunction("b", 0); unsigned c = addFunction("c", 0);
TermList x = var(0);
TermList y = var(1);
TermList z = var(2);
TermList aConst = constant(a);
TermList bConst = constant(b);
TermList cConst = constant(c);
Formula* ltXY = atom(lit(lt, true, {x, y}));
Formula* ltYZ = atom(lit(lt, true, {y, z}));
Formula* ltXZ = atom(lit(lt, true, {x, z}));
Formula* premise = andF({ltXY, ltYZ});
Formula* implication = impF(premise, ltXZ);
Formula* transitivity = forallF(2, forallF(1, forallF(0, implication)));
Formula* ltAB = atom(lit(lt, true, {aConst, bConst}));
Formula* ltBC = atom(lit(lt, true, {bConst, cConst}));
Formula* ltAC = atom(lit(lt, true, {aConst, cConst}));
Unit* ax1 = axiomF(transitivity);
Unit* ax2 = axiomF(ltAB);
Unit* ax3 = axiomF(ltBC);
Unit* conj = conjectureF(ltAC);
Problem* prb = problem({ax1, ax2, ax3, conj});
std::cout << "Problem: Prove transitivity of <" << std::endl;
std::cout << " Axiom 1: forall x,y,z. (x < y & y < z) => x < z" << std::endl;
std::cout << " Axiom 2: a < b" << std::endl;
std::cout << " Axiom 3: b < c" << std::endl;
std::cout << " Goal: a < c" << std::endl;
std::cout << std::endl;
ProofResult result = prove(prb);
if (result == ProofResult::PROOF) {
std::cout << "PROVED!" << std::endl << std::endl;
Unit* refutation = getRefutation();
printProof(std::cout, getRefutation());
auto steps = extractProof(refutation);
std::cout << "Proof steps:" << std::endl;
for (const auto& step : steps) {
std::cout << " [" << step.id << "] ";
if (step.isInput()) {
std::cout << step.inputTypeName();
} else {
std::cout << step.ruleName();
if (!step.premiseIds.empty()) {
std::cout << " from {";
for (size_t i = 0; i < step.premiseIds.size(); i++) {
if (i > 0) std::cout << ", ";
std::cout << step.premiseIds[i];
}
std::cout << "}";
}
}
std::cout << ": ";
if (step.clause()) {
std::cout << clauseToString(step.clause());
}
std::cout << std::endl;
}
} else {
std::cout << "Failed to prove (result: " << static_cast<int>(result) << ")" << std::endl;
}
delete prb;
return result == ProofResult::PROOF ? 0 : 1;
}