Skip to content

Refactor and extend InlineDirectives #309

@madmike200590

Description

@madmike200590

Currently, InlineDirectives is only a wrapper around something that could be an EnumMap.
It is only possible to have one instance of each directive and the only supported directive is enum_predicate_is which serves to designate one(!) predicate as having enumeration character, i.e. enables programmatic access to unique identifier terms for instances of that predicate.

I think it would make sense to refactor and extend directives in Alpha as follows:

Convert enumeration directive to built-in predicate

Consider the following simple program:

#enum_predicate_is enum_thing/3.

thing(1..5).

thing_idx(IDX) :- thing(X), enum_thing(things, X, IDX).

The designated "enumeration predicate" enum_thing is used to "generate" a unique numeric identifier for each X such that thing(X). This feature can be used to enumerate (i.e. assign numeric identifiers to) arbitrary, especially non-numeric terms, as happens e.g. in Alpha's AggregateRewriting transformation.
Since the actual identifier of the "enumeration" is the first term of the enumeration atom (things in above example), it seems redundant to separately declare arbitrary predicates as enumerations. Instead, users should be able to simply use a built-in predicate for this purpose and omit the declaration through a directive, see:

thing(1..5).
thing_idx(IDX) :- thing(X), &enum(things, X, IDX).
Add "transient" directive for intermediate predicates

Consider the following (stratified) program where complete/1 is true for every X such that part_a(X) and part_b(X) hold while blocked(X) is false:

part_a(1..5).
part_b(3..7).
blocked(4).
blocked(5).

both_parts(X) :- part_a(X), part_b(X).
complete(X) :- both_parts(X), not blocked(X).
<further rules depending on complete/1>

The predicate of interest in the answer set is complete/1, both_parts/1 is a "helper predicate" that is used to keep the rule deriving complete(X) shorter. Larger programs dealing with real-world problems may contain a lot of similar snippets where rules define helper predicates that are not needed once all rules directly depending on the helper predicate have been evaluated (by StratifiedEvaluation, which has a deterministic evaluation order and therefore awareness of when all instances of a predicate are known). It would make sense to be able to add a directive #transient both_parts/1. to the above program, instructing StratifiedEvaluation to "forget" instances of transient predicates as soon as it is safe to do so - in this case when all ground instances of complete(X) :- both_parts(X), not blocked(X). are known.

Add directives for cardinality constraints between relationships

Basically everything that can be defined as a cardinality constraint in an entity-relationship-diagram would be a useful thing to have a syntactic short-hand for in ASP, e.g. #cardinality{ object(X) : object_property(X : _) } = 1 : ?, which would be rewritten into :- object(X), not object_property(X, _).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions