diff --git a/include/anthem/AST.h b/include/anthem/AST.h index bc5e4e6..830e71e 100644 --- a/include/anthem/AST.h +++ b/include/anthem/AST.h @@ -95,6 +95,11 @@ struct Constant struct Function { + Function(std::string &&name) + : name{std::move(name)} + { + } + Function(std::string &&name, std::vector &&arguments) : name{std::move(name)}, arguments{std::move(arguments)} diff --git a/include/anthem/Term.h b/include/anthem/Term.h index 132426f..ba008aa 100644 --- a/include/anthem/Term.h +++ b/include/anthem/Term.h @@ -57,6 +57,23 @@ struct TermTranslateVisitor return std::make_unique(ast::SpecialInteger::Type::Supremum); case Clingo::SymbolType::String: return std::make_unique(std::string(symbol.string())); + case Clingo::SymbolType::Function: + { + auto function = std::make_unique(symbol.name()); + function->arguments.reserve(symbol.arguments().size()); + + for (const auto &argument : symbol.arguments()) + { + auto translatedArgument = visit(argument, term, context); + + if (!translatedArgument) + throwErrorAtLocation(term.location, "could not translate argument", context); + + function->arguments.emplace_back(std::move(translatedArgument.value())); + } + + return function; + } default: throwErrorAtLocation(term.location, "symbol type not supported", context); } diff --git a/tests/TestTranslation.cpp b/tests/TestTranslation.cpp index 370c579..4c6ddf4 100644 --- a/tests/TestTranslation.cpp +++ b/tests/TestTranslation.cpp @@ -90,6 +90,14 @@ TEST_CASE("[translation] Rules are translated correctly", "[translation]") REQUIRE(output.str() == "(#true -> p)\n"); } + SECTION("function") + { + input << ":- not p(I), I = 1..n."; + anthem::translate("input", input, context); + + REQUIRE(output.str() == "((exists X1 (X1 in I and not p(X1)) and exists X2, X3 (X2 in I and X3 in 1..n and X2 = X3)) -> #false)\n"); + } + SECTION("disjunctive fact (no arguments)") { input << "q; p.";