Search code examples
answer-set-programmingclingo

How to define OR condition in Clingo


I'm new to Clingo.

I want to know how to express an OR condition inside a count aggregate.

I'm writing this rule.

countPreviousSlots(C1, C2, TotalCount) :-
    firstLecture(C2, S2, G2, I2),
    TotalCount = #count{S1,G1,I1 : slot(S1, G1, I1, C1), (S1 < S2; (S1==S2, G1 < G2); (S1==S2, G1==G2, I1 < I2))},
    slot(_, _, _, _, C1).

But the round brackets aren't admitted by clingo. How do I have to to formulate this condition in clingo?

And what's the difference if I move the condition and I write:

countPreviousSlots(C1, C2, TotalCount) :-
    firstLecture(C2, S2, G2, I2),
    TotalCount = #count{S1,G1,I1 : slot(S1, G1, I1, C1)},
    slot(_, _, _, _, C1), (S1 < S2; (S1==S2, G1 < G2); (S1==S2, G1==G2, I1 < I2)).

Solution

  • You can formulate the lexicographic ordering with a further predicate. Disjunction can be nicely described with multiple rules with the same head. Here is a possible example

    num(1..2).
    
    lexorder(X1, X2, Y1, Y2) :-
      num(X1),
      num(X2),
      num(Y1),
      num(Y2),
      X1 < Y1.
    
    lexorder(X1, X2, Y1, Y2) :-
      num(X1),
      num(X2),
      num(Y1),
      num(Y2),
      X1 = Y1,
      X2 < Y2.
    

    The difference is that you count differently. The set you are creating in the first version {...} is smaller than in the second version as it has less constraints. Moreover, in the second version, some variables are not bounded (S1) such that the grounder will not know how to replace S1 with an atom. The variables inside the count statement are scoped between the brackets.