lparse/clingo: How to say AllOf(a,b,c) :- condition? - answer-set-programming

The following makes one or more literals true:
a,b,c :- condition.
a;b;c :- condition.
In the above a,b,c,condition is a valid model, but also (a,condition), (a,b,condition), etc. I want all of a, b, c to be true, always, if condition is true.
I can write the following to force a,b,c to be always true together.
:- condition, a, not b.
:- condition, b, not c.
:- condition, c, not a.
but these become very verbose and bug prone for complex rules.

You can write
3 { a ; b ; c } 3 :- condition.
That means that at least 3 and at most 3 atoms in the curly brackets are defined as true if the condition is true.
The constraints which you wrote have a very different meaning, for example the first constraint requires that some other rule must not define truth of condition and a unless there is also a rule that defines b to be true.

Related

Creating 2 occurrence predicates out of another predicate based on min/max number of other index in the original predicate

I have the following input in Clingo:
val(a,2,3).
val(a,4,5).
val(b,0,6).
val(b,1,2).
the required is to have two predicates representing the first and second occurrence of each letter where the first one is the minimum number of the third index of val (case 1: only based on min of 3rd index), in case they are the same, then based on minimum number of the second index (case 2: both conditions).
Note that the maximum number of occurrences for each letter is 2.
The expected results is having two predicates with these values (only for this case, as sometimes the input is different):
first(a,2,3), first(b,1,2), second(a,4,5), second(b,0,6)
I tried the following code for case 1:
val(X,Y,W) :- val(X,Y,W).
first(X,Y,Z) :- val(X,Y,Z), not val(X,Y',Z'), Z'>Z,Y'!=Y.
second(X,Y,Z) :- val(X,Y,Z), not first(X,_,_).
but an error messages showed saying that Z' and Y' are unsafe.
Yes, Z' and Y' are unsafe because they do not appear in any positive predicate.
Moreover:
val(X,Y,W) :- val(X,Y,W). is a tautology and, therefore, it is useless;
it is not clear to me why you are imposing that Y'!=Y;
not first(X,_,_) is wrong, since it is checking that there doesn't exist ANY predicate first with variable X in the first argument (but this should always happen).
If I've correctly understood your requirements, this should be the correct implementation:
first(X,Y,Z) :- val(X,Y,Z), val(X,Y',Z'), Z'>Z . % case 1
first(X,Y,Z) :- val(X,Y,Z), val(X,Y',Z'), Z'=Z, Y'>Y . % case 2
second(X,Y,Z) :- val(X,Y,Z), not first(X,Y,Z) .

if statement with 'or' operator gives different results when conditions are swapped

I'm using strfind with an 'or' comparison like so:
name='hello';
if strfind(name,'hello') | strfind(name,'hi')
disp('yes!')
end
>> yes!
The if statement must evaluate as true, since yes! is displayed.
In contrast, MATLAB doesn't return yes! if the statements are swapped:
if strfind(name,'hi') | strfind(name,'hello')
disp('yes!')
end
Why?
This is because short-circuiting. Short-circuited logical operators are a thing to speed up code. You can have
if veryShort | superlongComputation
so what MATLAB does is first evaluate veryShort and if it is true, then no need to evaluate the second one! The if condition is already met.
In your case strfind(name,'hello') returns 1, but strfind(name,'hi') returns [].
In the first example, as the first thing evaluated returns 1, you get to the display. However in the second case, it returns [], therefore MATLAB evaluates the second thing in the if, and returns 1. Then MATLAB applies the or operations where [] | 1 is an 0x0 empty logical array, so the if is not true.
Note, generally you want to use || to enforce short-circuiting, but | also does it, if it is inside a while or an if:
https://uk.mathworks.com/matlabcentral/answers/99518-is-the-logical-operator-in-matlab-a-short-circuit-operator
Both of the following conditions are empty []:
name='hello';
strfind(name,'hello') | strfind(name,'hi'); % = []
strfind(name,'hi') | strfind(name,'hello'); % = []
As referenced in Ander's answer, the | operator is using short circuiting to skip evaluation of the second condition if the first is false (or empty).
Some quick debugging will give you better understanding if we ignore short-circuiting:
strfind(name,'hi'); % = []
strfind(name,'hello'); % = 1
In both cases you are doing "if empty or non-zero", which is empty and "if []" is false (that conditional statement won't be executed).
What you want to use to be explicit is something like this:
if ~isempty(strfind(name, 'hello')) & ~isempty(strfind(name, 'hi'))
disp('yes!')
end
Here, we guarantee that everything being evaluated in the if statement is a Boolean variable, not empty or an index like strfind returns, so unexpected results are less likely.
There are simpler methods, like using strcmp or ismember if your strings should match exactly. Or contains if you have R2016b or newer:
if contains('hello', {'hello','hi'})
disp('yes!');
end

openscad If statement issue with variable

I have a problem with If statement in OpenScad.
I have 4 variables
a=20;
b=14;
w=1;
c=16;
I want to check witch number is bigger a or b.
And after depending who is smaller to take the value of smaller variable(in our case b < a) and to make a simple operation with c variable ( c=b-w).
I tried like this but it doesn't work.
a=20;
b=14;
w=1;
c=16;
if(a>b)
{
c=b-w;
}
if (a<b)
{
c=a-w;
}
if (a==b)
{
c=a-w;
}
It seems logic, but in openscad as I understood you can't change the value of variable inside a If statement. What trick can I use in order to get my goal.
Thank you!
in the 3. leg you confused the assignment-operator „=“ with the equal-operator „==“ (correct if (a==b)).
in your 3. leg you do the same as in the 2., so you could handle both as an „else“-leg.
Correct: assignment is not allowed in if-statement. In openscad you can use the ? operator instead:
c = a > b ? b-w : a-w;
After = follows the condition. The statement after the ? becomes the value if the condition is true, and the statement after the : becomes the value if the condition is false. Nested conditions are possible, e.g. your conditions:
c = a > b ? b-w : (a < b ? a-w : a-w);
More information in the documentation.
OpenSCAD's variable assignment is different. You can only assign variables inside a bracket. So c = b - w will only be assigned inside the if bracket. Outside if this bracket it will still be 16. Don't ask me why. You can read more in the Documentation of OpenSCAD.
c = min(c,min(a,b)/2-w);
this also solve the problem )

How to match specific tokens in UIMA Ruta?

DECLARE A,B;
DECLARE Annotation C(Annotation firstA, Annotation secondA,...);
"token1|token2|...|tokenn" -> A;
"token3|token4" -> B;
A A B {->MARK(C,1,3)};
I did with GATHER
(A COMMA A B) {-> GATHER(C,1,4,"firstA"=1,"secondA" = 3,"B"=4)};
But how about in case of unknown sequence of A type? as below, how can it be possible to store all A in features? The number of features are also unknown. In plan java, we declare String array and can add element, but in Ruta seems to be no as such process.
(A (COMMA A)+ B) {-PARTOF(C) -> GATHER(C,beginPosition,endPosition,"firstA"=1,"secondA" = 3,"thirdA"=?,so on)};
Annotations in UIMA refer to the complete span, from the begin offset to the end offset. So, if you want to specify something with two elements, then a simple annotation is not sufficient. You cannot create an annotation of the type C that covers the first A and the B but not the second A.
However, you can store the important information in feature values. How to implement it depends on various things.
If there are always exactly two annotation you want to remember, then add two features to type C and assign the feature values in the given rule, e.g., by CREATE(C,1,3,"first" = A, "second" = B ).
You can also use different actions like GATHER, or use one FSArray feature in order to store the annotations.
A complete example with a FSArray:
DECLARE A, B;
DECLARE Annotation C (FSArray as, B b);
"A" -> A;
"B" -> B;
(A (COMMA A)+ B){-PARTOF(C) -> CREATE(C, "as" = A, "b" = B)};
If applied on a text like "A, A, A B", the last rule creates one annotation of type C that stores three A annotations in the feature "as" and one B annotation in the feature "b"

clauses for the same predicate should be grouped

Here I want to make a prolog implementation that will generate the list of permutations of n,n+1,...2*n-1, having the absolute difference between 2 consecutive values <=2.
Ex: for n=4 the list on which I make the permutations would be [4,5,6,7] , a valid permutation would be [5,4,6,7] and not a valid one would be [7,4,6,5] because 7-4 is 3 . The problem is that I get the following error clauses for the same predicate should be grouped. I don't understand what I did wrong..Please help me
domains
el=integer
list=el*
lista=list*
predicates
perm(list,list)
permutations(integer,list)
delete(integer,list,list)
generate(integer,lista)
create(integer,list)
create_list(integer,integer,list)
permutations_aux(integer,list)
diff(list,integer).
clauses
create(N,L):-
M = 2*N,
create_list(N,M,L).
create_list(N,M,[N|R]):-
N<M,
N1=N+1,
create_list(N1,M,R).
create_list(M,M,[]).
perm([],[]).
perm(Y,[A|X]):-
delete(A,Y,Y1),
perm(Y1,X).
delete(A,[A|X],X).
delete(A,[B|X],[B|Y]):-
delete(A,X,Y).
permutations(N,X):-
create(N,X1),
perm(X1,X).
diff(X,2).
permutations_aux(N,X):-
permutations(N,X).
diff([],_).
diff([_],_).
diff([X,Y|T],M):-
abs(Y-X) <=M,!,
diff([Y|T],M).
generate(N,R):-
findall(X,permutations_aux(N,X),R).
goal
generate(4,P),
write(P).
The error or warning:
Clauses for the same predicate should be grouped
Means that you have interleaved definition of different clauses. In other words, clauses for a predicate with the same name should all be defined together in a group. Such as:
foo(X) :-
some stuff
foo(Y) :-
some stuff
bar(X) :-
some stuff
bar(Y) :-
some stuff
You will get the warning/error if you do:
foo(X) :-
some stuff
bar(X) :-
some stuff
foo(Y) :-
some stuff
bar(Y) :-
some stuff
Your error is that you have a period after perm(X1,X). in your permutations clause. It should be a comma:
permutations(N,X):-
create(N,X1),
perm(X1,X). <--- Error here
diff(X,2).
permutations_aux(N,X):-
permutations(N,X).
diff([],_).
So it really thinks you have:
permutations(N,X):-
create(N,X1),
perm(X1,X).
diff(X,2).
permutations_aux(N,X):-
permutations(N,X).
diff([],_).
Which is an interleave of definitions for diff.