34     BindingStore bindingStore(clause);
 
   35     auto atoms = getBodyLiterals<Atom>(*clause);
 
   36     std::vector<unsigned int> newOrder(atoms.size());
 
   39     while (numAdded < atoms.size()) {
 
   42         auto minIdx = std::distance(costs.begin(), std::min_element(costs.begin(), costs.end()));
 
   43         const auto* nextAtom = atoms[minIdx];
 
   44         assert(nextAtom != 
nullptr && 
"nullptr atoms should have maximal cost");
 
   47         for (
const auto* arg : nextAtom->getArguments()) {
 
   48             if (
const auto* var = 
dynamic_cast<const Variable*
>(arg)) {
 
   49                 bindingStore.bindVariableStrongly(var->getName());
 
   53         newOrder[numAdded] = minIdx;  
 
   54         atoms[minIdx] = 
nullptr;      
 
   62 std::unique_ptr<SipsMetric> 
SipsMetric::create(
const std::string& heuristic, 
const TranslationUnit& tu) {
 
   63     if (heuristic == 
"strict")
 
   64         return std::make_unique<StrictSips>();
 
   65     else if (heuristic == 
"all-bound")
 
   66         return std::make_unique<AllBoundSips>();
 
   67     else if (heuristic == 
"naive")
 
   68         return std::make_unique<NaiveSips>();
 
   69     else if (heuristic == 
"max-bound")
 
   70         return std::make_unique<MaxBoundSips>();
 
   71     else if (heuristic == 
"max-ratio")
 
   72         return std::make_unique<MaxRatioSips>();
 
   73     else if (heuristic == 
"least-free")
 
   74         return std::make_unique<LeastFreeSips>();
 
   75     else if (heuristic == 
"least-free-vars")
 
   76         return std::make_unique<LeastFreeVarsSips>();
 
   77     else if (heuristic == 
"profile-use")
 
   79     else if (heuristic == 
"delta")
 
   80         return std::make_unique<DeltaSips>();
 
   81     else if (heuristic == 
"input")
 
   84     else if (heuristic == 
"delta-input")
 
   89     return create(
"all-bound", tu);
 
   93         const std::vector<Atom*> atoms, 
const BindingStore& )
 const {
 
   95     std::vector<double> cost;
 
   96     for (
const auto* atom : atoms) {
 
   97         cost.push_back(atom == 
nullptr ? std::numeric_limits<double>::max() : 0);
 
   99     assert(atoms.size() == cost.size() && 
"each atom should have exactly one cost");
 
  104         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  106     std::vector<double> cost;
 
  107     for (
const auto* atom : atoms) {
 
  108         if (atom == 
nullptr) {
 
  109             cost.push_back(std::numeric_limits<double>::max());
 
  113         int arity = atom->getArity();
 
  114         int numBound = bindingStore.numBoundArguments(atom);
 
  115         cost.push_back(arity == numBound ? 0 : 1);
 
  117     assert(atoms.size() == cost.size() && 
"each atom should have exactly one cost");
 
  122         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  124     std::vector<double> cost;
 
  125     for (
const auto* atom : atoms) {
 
  126         if (atom == 
nullptr) {
 
  127             cost.push_back(std::numeric_limits<double>::max());
 
  131         int arity = atom->getArity();
 
  132         int numBound = bindingStore.numBoundArguments(atom);
 
  133         if (arity == numBound) {
 
  135         } 
else if (numBound >= 1) {
 
  141     assert(atoms.size() == cost.size() && 
"each atom should have exactly one cost");
 
  146         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  148     std::vector<double> cost;
 
  149     for (
const auto* atom : atoms) {
 
  150         if (atom == 
nullptr) {
 
  151             cost.push_back(std::numeric_limits<double>::max());
 
  155         int arity = atom->getArity();
 
  156         int numBound = bindingStore.numBoundArguments(atom);
 
  157         if (arity == numBound) {
 
  160         } 
else if (numBound == 0) {
 
  165             cost.push_back(1 / numBound);
 
  168     assert(atoms.size() == cost.size() && 
"each atom should have exactly one cost");
 
  173         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  175     std::vector<double> cost;
 
  176     for (
const auto* atom : atoms) {
 
  177         if (atom == 
nullptr) {
 
  178             cost.push_back(std::numeric_limits<double>::max());
 
  182         int arity = atom->getArity();
 
  183         int numBound = bindingStore.numBoundArguments(atom);
 
  187         } 
else if (numBound == 0) {
 
  192             cost.push_back(1 - numBound / arity);
 
  195     assert(atoms.size() == cost.size() && 
"each atom should have exactly one cost");
 
  200         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  202     std::vector<double> cost;
 
  203     for (
const auto* atom : atoms) {
 
  204         if (atom == 
nullptr) {
 
  205             cost.push_back(std::numeric_limits<double>::max());
 
  209         cost.push_back(atom->getArity() - bindingStore.numBoundArguments(atom));
 
  215         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  217     std::vector<double> cost;
 
  218     for (
const auto* atom : atoms) {
 
  219         if (atom == 
nullptr) {
 
  220             cost.push_back(std::numeric_limits<double>::max());
 
  225         std::set<std::string> freeVars;
 
  227             if (bindingStore.isBound(var.getName())) {
 
  228                 freeVars.insert(var.getName());
 
  231         cost.push_back(freeVars.size());
 
  237         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  241     std::vector<double> cost;
 
  242     for (
const auto* atom : atoms) {
 
  243         if (atom == 
nullptr) {
 
  244             cost.push_back(std::numeric_limits<double>::max());
 
  249         int arity = atom->getArity();
 
  256         int numBound = bindingStore.numBoundArguments(atom);
 
  257         int numFree = arity - numBound;
 
  259         value *= (numFree * 1.0) / arity;
 
  265         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  267     std::vector<double> cost;
 
  268     for (
const auto* atom : atoms) {
 
  269         if (atom == 
nullptr) {
 
  270             cost.push_back(std::numeric_limits<double>::max());
 
  274         int arity = atom->getArity();
 
  275         int numBound = bindingStore.numBoundArguments(atom);
 
  276         if (arity == numBound) {
 
  290         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  292     std::vector<double> cost;
 
  293     for (
const auto* atom : atoms) {
 
  294         if (atom == 
nullptr) {
 
  295             cost.push_back(std::numeric_limits<double>::max());
 
  299         const auto& relName = atom->getQualifiedName();
 
  300         int arity = atom->getArity();
 
  301         int numBound = bindingStore.numBoundArguments(atom);
 
  302         if (arity == numBound) {
 
  316         const std::vector<Atom*> atoms, 
const BindingStore& bindingStore)
 const {
 
  318     std::vector<double> cost;
 
  319     for (
const auto* atom : atoms) {
 
  320         if (atom == 
nullptr) {
 
  321             cost.push_back(std::numeric_limits<double>::max());
 
  325         const auto& relName = atom->getQualifiedName();
 
  326         int arity = atom->getArity();
 
  327         int numBound = bindingStore.numBoundArguments(atom);
 
  328         if (arity == numBound) {