Support declaring functions as integer

This adds a new syntax for declaring functions integer:

    #external integer(<function name>(<arity)).

If a function is declared integer, it may enable some variables to be
detected as integer as well.
This commit is contained in:
Patrick Lühne 2018-04-19 16:11:05 +02:00
parent 89aec98942
commit 159717f51c
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 45 additions and 6 deletions

View File

@ -149,6 +149,7 @@ struct FunctionDeclaration
std::string name;
size_t arity;
Domain domain{Domain::General};
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -190,7 +190,7 @@ struct StatementVisitor
const auto fail =
[&]()
{
throw LogicException(statement.location, "only #external declarations of the form “#external <predicate name>(<arity>). supported");
throw LogicException(statement.location, "only #external declarations of the form “#external <predicate name>(<arity>). or #external integer(<function name>(<arity>)). supported");
};
if (!external.body.empty())
@ -204,6 +204,47 @@ struct StatementVisitor
if (predicate.arguments.size() != 1)
fail();
const auto handleIntegerDeclaration =
[&]()
{
// Integer function declarations are treated separately if applicable
if (strcmp(predicate.name, "integer") != 0)
return false;
if (predicate.arguments.size() != 1)
return false;
const auto &functionArgument = predicate.arguments.front();
if (!functionArgument.data.is<Clingo::AST::Function>())
return false;
const auto &function = functionArgument.data.get<Clingo::AST::Function>();
if (function.arguments.size() != 1)
return false;
const auto &arityArgument = function.arguments.front();
if (!arityArgument.data.is<Clingo::Symbol>())
return false;
const auto &aritySymbol = arityArgument.data.get<Clingo::Symbol>();
if (aritySymbol.type() != Clingo::SymbolType::Number)
return false;
const size_t arity = aritySymbol.number();
auto functionDeclaration = context.findOrCreateFunctionDeclaration(function.name, arity);
functionDeclaration->domain = ast::Domain::Integer;
return true;
};
if (handleIntegerDeclaration())
return;
const auto &arityArgument = predicate.arguments.front();
if (!arityArgument.data.is<Clingo::Symbol>())

View File

@ -49,12 +49,9 @@ struct TermDomainVisitor
return ast::Domain::General;
}
static ast::Domain visit(ast::Function &)
static ast::Domain visit(ast::Function &function)
{
// Functions may return values of any type
// TODO: implement explicit integer specifications
return ast::Domain::General;
return function.declaration->domain;
}
static ast::Domain visit(ast::Integer &)