62 inline QualifiedName
makeRelationName(
const QualifiedName& orig,
const std::string&
type,
int num = -1) {
63 QualifiedName newName(
toString(orig));
66 newName.append((
const std::string&)std::to_string(num));
79 infoRelation->setQualifiedName(name);
84 auto infoClause =
new Clause();
85 auto infoClauseHead =
new Atom();
86 infoClauseHead->setQualifiedName(name);
89 infoRelation->addAttribute(mk<Attribute>(
"clause_num",
QualifiedName(
"number")));
90 infoClauseHead->addArgument(mk<NumericConstant>(originalClauseNum));
93 std::vector<std::string> headVariables;
98 int functorNumber = 0;
99 int aggregateNumber = 0;
100 auto getArgInfo = [&](
Argument* arg) -> std::string {
103 }
else if (
auto* constant =
dynamic_cast<Constant*
>(arg)) {
106 if (isA<UnnamedVariable>(arg)) {
109 if (isA<Functor>(arg)) {
112 if (isA<Aggregator>(arg)) {
116 fatal(
"Unhandled argument type");
121 headVariables.push_back(getArgInfo(arg));
125 std::stringstream headVariableString;
126 headVariableString <<
join(headVariables,
",");
129 infoRelation->addAttribute(mk<Attribute>(std::string(
"head_vars"), QualifiedName(
"symbol")));
130 infoClauseHead->addArgument(mk<StringConstant>(
toString(
join(headVariables,
","))));
136 const Atom* atom =
nullptr;
137 if (isA<Atom>(lit)) {
138 atom =
static_cast<Atom*
>(lit);
139 }
else if (isA<Negation>(lit)) {
140 atom =
static_cast<Negation*
>(lit)->getAtom();
141 }
else if (isA<ProvenanceNegation>(lit)) {
142 atom =
static_cast<ProvenanceNegation*
>(lit)->getAtom();
146 if (atom !=
nullptr || isA<BinaryConstraint>(lit)) {
147 infoRelation->addAttribute(
148 mk<Attribute>(std::string(
"rel_") + std::to_string(
i), QualifiedName(
"symbol")));
151 if (atom !=
nullptr) {
152 std::string relName =
toString(atom->getQualifiedName());
155 if (isA<Atom>(lit)) {
156 std::string atomDescription = relName;
158 for (
auto& arg : atom->getArguments()) {
159 atomDescription.append(
"," + getArgInfo(arg));
162 infoClauseHead->addArgument(mk<StringConstant>(atomDescription));
164 }
else if (isA<Negation>(lit)) {
165 infoClauseHead->addArgument(mk<StringConstant>(
"!" + relName));
174 if (
auto con =
dynamic_cast<BinaryConstraint*
>(lit)) {
178 constraintDescription.append(
"," + getArgInfo(con->getLHS()));
179 constraintDescription.append(
"," + getArgInfo(con->getRHS()));
181 infoClauseHead->addArgument(mk<StringConstant>(constraintDescription));
185 infoRelation->addAttribute(mk<Attribute>(
"clause_repr", QualifiedName(
"symbol")));
186 infoClauseHead->addArgument(mk<StringConstant>(
toString(originalClause)));
189 infoClause->setHead(Own<Atom>(infoClauseHead));
190 Program& program = translationUnit.
getProgram();
191 program.
addClause(Own<Clause>(infoClause));
193 return Own<Relation>(infoRelation);
199 "attempting to transform non-eqrel relation");
200 assert(
rel.getArity() == 2 &&
"eqrel relation not binary");
206 auto transitiveClause =
new Clause();
207 auto transitiveClauseHead =
new Atom(
rel.getQualifiedName());
208 transitiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
209 transitiveClauseHead->addArgument(mk<ast::Variable>(
"z"));
211 auto transitiveClauseBody =
new Atom(
rel.getQualifiedName());
212 transitiveClauseBody->addArgument(mk<ast::Variable>(
"x"));
213 transitiveClauseBody->addArgument(mk<ast::Variable>(
"y"));
215 auto transitiveClauseBody2 =
new Atom(
rel.getQualifiedName());
216 transitiveClauseBody2->addArgument(mk<ast::Variable>(
"y"));
217 transitiveClauseBody2->addArgument(mk<ast::Variable>(
"z"));
219 transitiveClause->setHead(
Own<Atom>(transitiveClauseHead));
220 transitiveClause->addToBody(
Own<Literal>(transitiveClauseBody));
221 transitiveClause->addToBody(
Own<Literal>(transitiveClauseBody2));
226 auto symClause =
new Clause();
227 auto symClauseHead =
new Atom(
rel.getQualifiedName());
228 symClauseHead->addArgument(mk<ast::Variable>(
"x"));
229 symClauseHead->addArgument(mk<ast::Variable>(
"y"));
231 auto symClauseBody =
new Atom(
rel.getQualifiedName());
232 symClauseBody->addArgument(mk<ast::Variable>(
"y"));
233 symClauseBody->addArgument(mk<ast::Variable>(
"x"));
235 symClause->setHead(
Own<Atom>(symClauseHead));
241 auto reflexiveClause =
new Clause();
242 auto reflexiveClauseHead =
new Atom(
rel.getQualifiedName());
243 reflexiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
244 reflexiveClauseHead->addArgument(mk<ast::Variable>(
"x"));
246 auto reflexiveClauseBody =
new Atom(
rel.getQualifiedName());
247 reflexiveClauseBody->addArgument(mk<ast::Variable>(
"x"));
248 reflexiveClauseBody->addArgument(mk<UnnamedVariable>());
250 reflexiveClause->setHead(
Own<Atom>(reflexiveClauseHead));
251 reflexiveClause->addToBody(
Own<Literal>(reflexiveClauseBody));
256 Own<Argument> getNextLevelNumber(
const std::vector<Argument*>& levels) {
257 if (levels.empty())
return mk<NumericConstant>(0);
259 auto max = levels.size() == 1
263 return mk<IntrinsicFunctor>(
"+", std::move(max), mk<NumericConstant>(1));
268 Program& program = translationUnit.getProgram();
270 for (
auto relation : program.getRelations()) {
277 for (
auto relation : program.getRelations()) {
289 relation->addAttribute(mk<Attribute>(std::string(
"@rule_number"), QualifiedName(
"number")));
290 relation->addAttribute(mk<Attribute>(std::string(
"@level_number"), QualifiedName(
"number")));
296 struct M :
public NodeMapper {
297 using NodeMapper::operator();
299 Own<Node> operator()(Own<Node> node)
const override {
301 if (
auto atom =
dynamic_cast<Atom*
>(node.get())) {
302 atom->addArgument(mk<UnnamedVariable>());
303 atom->addArgument(mk<UnnamedVariable>());
304 }
else if (
auto neg =
dynamic_cast<Negation*
>(node.get())) {
305 auto atom = neg->getAtom();
306 atom->addArgument(mk<UnnamedVariable>());
307 atom->addArgument(mk<UnnamedVariable>());
317 clause->getHead()->apply(M());
321 clause->getHead()->addArgument(mk<NumericConstant>(0));
322 clause->getHead()->addArgument(mk<NumericConstant>(0));
324 std::vector<Argument*> bodyLevels;
326 for (
size_t i = 0;
i < clause->getBodyLiterals().
size();
i++) {
327 auto lit = clause->getBodyLiterals()[
i];
333 if (
auto atom =
dynamic_cast<Atom*
>(lit)) {
334 atom->addArgument(mk<UnnamedVariable>());
335 atom->addArgument(mk<ast::Variable>(
"@level_num_" + std::to_string(
i)));
336 bodyLevels.push_back(
new ast::Variable(
"@level_num_" + std::to_string(
i)));
341 clause->getHead()->addArgument(mk<NumericConstant>(clauseNum));
342 clause->getHead()->addArgument(getNextLevelNumber(bodyLevels));