Exemple #1
0
void act(ActionBlock &action_block, Relation &results, Index &assertions, Index &retractions) {
  if (action_block.action_variables.begin != action_block.action_variables.end) {
    cerr << "[ERROR] Action variables are unsupported." << endl;
    return;
  }
  Action *action = action_block.actions.begin;
  for (; action != action_block.actions.end; ++action) {
    switch (action->type) {
      case ASSERT_FACT:
      case RETRACT_FACT: {
        if (action->get.atom.type == ATOM) {
          if (action->type == RETRACT_FACT) {
            cerr << "[ERROR] Retraction of atoms is currently unsupported." << endl;
            return;
          }
          act(action->get.atom.get.atom, results);
          continue;
        }
        if (action->get.atom.type != FRAME) {
          cerr << "[ERROR] For now, supporting only assertion of frames/triples." << endl;
          return;
        }
        Frame frame = action->get.atom.get.frame;
        Tuple triple(3);
        if (frame.object.type == LIST || frame.object.type == FUNCTION) {
          cerr << "[ERROR] Not supporting lists or functions in action target." << endl;
          return;
        }
        if (frame.object.type == CONSTANT) {
          triple[0] = frame.object.get.constant;
        }
        pair<Term, Term> *slot = frame.slots.begin;
        for (; slot != frame.slots.end; ++slot) {
          if (slot->first.type == LIST || slot->first.type == FUNCTION ||
              slot->second.type == LIST || slot->second.type == FUNCTION) {
            cerr << "[ERROR] Not supporting lists or function in action target." << endl;
            return;
          }
          if (slot->first.type == CONSTANT) {
            triple[1] = slot->first.get.constant;
          }
          if (slot->second.type == CONSTANT) {
            triple[2] = slot->second.get.constant;
          }
          if (!results.empty() && frame.object.type == CONSTANT && slot->first.type == CONSTANT && slot->second.type == CONSTANT) {
            if (action->type == ASSERT_FACT) {
              assertions.insert(triple);
            } else {
              retractions.insert(triple);
            }
            continue;
          }
          Relation::iterator tuple = results.begin();
          for (; tuple != results.end(); ++tuple) {
            if (frame.object.type == VARIABLE) {
              triple[0] = tuple->at(frame.object.get.variable);
            }
            if (slot->first.type == VARIABLE) {
              triple[1] = tuple->at(slot->first.get.variable);
            }
            if (slot->second.type == VARIABLE) {
              triple[2] = tuple->at(slot->second.get.variable);
            }
            if (action->type == ASSERT_FACT) {
              assertions.insert(triple);
            } else {
              retractions.insert(triple);
            }
          }
        }
        return;
      }
      default: {
        cerr << "[ERROR] Currently supporting on ASSERT_FACT and RETRACT_FACT actions." << endl;
        return;
      }
    }
  }
}
Exemple #2
0
void query(Condition &condition, set<varint_t> &allvars, Relation &results) {
  deque<void*> negated;
  Relation intermediate;
  switch (condition.type) {
    case ATOMIC: {
      query(condition.get.atom, allvars, results);
      return;
    }
    case CONJUNCTION: {
      Condition *subformula = condition.get.subformulas.begin;
      for (; subformula != condition.get.subformulas.end; ++subformula) {
        if (subformula->type == NEGATION) {
          negated.push_back((void*)subformula->get.subformulas.begin);
          continue;
        }
        Relation subresult;
        set<varint_t> newvars;
        // TODO vvv this won't work right if a non-special query
        // has not been performed first
        if (special(*subformula, intermediate, subresult)) {
          if (subformula == condition.get.subformulas.begin) {
            cerr << "[ERROR] Must have non-special query at beginning of conjunction." << endl;
          }
          intermediate.swap(subresult);
          continue;
        }
        query(*subformula, newvars, subresult);
        if (subformula == condition.get.subformulas.begin) {
          intermediate.swap(subresult);
        } else {
          vector<size_t> joinvars(allvars.size() + newvars.size());
          vector<size_t>::iterator jit = set_intersection(allvars.begin(),
              allvars.end(), newvars.begin(), newvars.end(), joinvars.begin());
          joinvars.resize(jit - joinvars.begin());
          join(intermediate, subresult, joinvars, intermediate);
        }
        allvars.insert(newvars.begin(), newvars.end());
      }
      break;
    }
    case DISJUNCTION: {
      cerr << "[ERROR] Disjunction is not supported." << endl;
      return;
    }
    case EXISTENTIAL: {
      // assuming all quantified variables are uniquely named in the scope of the rule
      Condition *subformula = condition.get.subformulas.begin;
      for (; subformula != condition.get.subformulas.end; ++subformula) {
        if (subformula->type == NEGATION) {
          negated.push_back((void*)subformula->get.subformulas.begin);
        }
        Relation subresult;
        query(*subformula, allvars, subresult);
        intermediate.splice(intermediate.end(), subresult);
      }
      break;
    }
    case NEGATION: {
      cerr << "[ERROR] This should never happen.  query should not be called directly on negated formulas." << endl;
      return;
    }
    default: {
      cerr << "[ERROR] Unhandled case " << (int)condition.type << " on line " << __LINE__ << endl;
      return;
    }
  }
// TODO deal with negation later, if at all
#if 1
  deque<void*>::iterator it = negated.begin();
  for (; !intermediate.empty() && it != negated.end(); ++it) {
    Relation negresult;
    Condition *cond = (Condition*) *it;
    if (special(*cond, intermediate, negresult)) {
      intermediate.sort();
      negresult.sort();
      Relation leftover(intermediate.size());
      Relation::iterator iit = set_difference(intermediate.begin(),
          intermediate.end(), negresult.begin(), negresult.end(),
          leftover.begin());
      Relation newinter;
      newinter.splice(newinter.end(), leftover,
                      leftover.begin(), iit);
      intermediate.swap(newinter);
      continue;
    }
    query(*((Condition*)(*it)), allvars, negresult);
    minusrel(intermediate, negresult, intermediate);
  }
#endif
  results.swap(intermediate);
}