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:
parent
89aec98942
commit
159717f51c
@ -149,6 +149,7 @@ struct FunctionDeclaration
|
||||
|
||||
std::string name;
|
||||
size_t arity;
|
||||
Domain domain{Domain::General};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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>())
|
||||
|
@ -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 &)
|
||||
|
Loading…
Reference in New Issue
Block a user