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

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) .

Related

find in range of a IDL array?

I am trying to find all indices in an array A, where the value larger than time0 and less than time1. In matlab I can do:
[M,F] = mode( A((A>=time0) & (A<=time1)) ) %//only interested in range
I have something similar in IDL but really slow:
tmpindex0 = where(A ge time0)
tmpindex1 = where(A lt time1)
M = setintersection(tmpindex0,tmpindex1)
where setintersection() is function find the intersected elements between two arrays. What is the fast alternative implementation?
You can combine your conditions:
M = where(A ge time0 and A lt time1, count)
Then M will contain indices into time0 and time1 while count will contain the number of indices. Generally, you want to check count before using M.
This works (slight modification from mgalloy answer):
M = where( (A ge time0) and (A lt time1), n_match, complement=F, n_complement=ncomp)
The parenthetical separation is not necessary but adds clarity. n_match contains the number of matches to your conditions whereas the complement F will contain the indices for the non-matches and ncomp will contain the number of non-matches.

clingo: placing element according to the rules

Hello i'm trying to learn more about clingo, have this terms: v(1,2).v(2,1).v(3,4).v(4,3), means that first element cannot be in the same row of the second element, the second cannot be in the same of the first, ecc.. would like to write some rules to find a matrix 2x2 in which element (I,J,N) are placed according to that limits. thanks in advance
v(1,2).v(2,1).v(3,4).v(4,3)
rows(1..2).
col(1..2).
1{m(I,J,N) : v(N)}1 :- rows(I), col(J).
1{m(I,J,N) : rows(I), col(J)}1 :- v(N).
...code...
output
[1,1,1][1,2,4][2,1,2][2,2,3]
[1,1,4][1,2,1][2,1,2][2,2,3]
[1,1,1][1,2,4][2,1,3][2,2,2]
[1,1,4][1,2,1][2,1,3][2,2,2]
The first rule
1{m(I,J,N) : v(N)}1 :- rows(I), col(J).
puts into each location of the matrix one v(N) but you do not have v(N) defined, you have v(N,M) defined.
The second rule
1{m(I,J,N) : rows(I), col(J)}1 :- v(N).
Puts each v(N) in exactly one row and column.
I suggest you replace v(X) by w(X) and define
w(N) :- v(N,_).
w(N) :- v(_,N).
That means you get all possible values form the v(X,Y) into w.

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.

How can i compare natural numbers in prolog?

I have a function that takes two arguments and compares if they are natural numbers in their unit form and if the first arg is bigger than the second!
So here is the code I've written but every time it gets me "no".
nat(0).
nat(s(X)) :- nat(X).
sum(X,0,X) :- nat(X).
sum(X,s(Y),s(Z)) :- sum(X,Y,Z).
gr(X,Y) :- nat(s(X)), nat(s(Y)), X>Y.
What goes wrong? Everything is in Prolog . the function is the gr() .
First, you probably want for sum rather this:
sum(0, Y, Y) :-
nat(Y).
sum(s(X), Y, s(Z)) :-
sum(X, Y, Z).
This is so that Prolog can recognize that the two clauses are exclusive by only looking at the first argument.
Now to your greater than:
% gr(X, Y) is true if X is greater than Y
gr(X, Y) :- sm(Y, X).
% sm(X, Y) is true if X is smaller than Y
sm(0, s(Y)) :-
nat(Y).
sm(s(X), s(Y)) :-
sm(X, Y).
To answer your actual question: what goes wrong is that the operator > works on integers (like 1 or 0 or -19), not on compound terms. The operator #> will work (see the documentation of the implementation you are using), but I have the feeling you might actually want to be explicit about it.

Is this the simplified version of this boolean expression? Or is this reviewer wrong

Cause I've tried doing the truth table unfortunately one has 3 literals and the other has 4 so i got confused.
F = (A+B+C)(A+B+D')+B'C;
and this is the simplified version
F = A + B + C
http://www.belley.org/etc141/Boolean%20Sinplification%20Exercises/Boolean%20Simplification%20Exercise%20Questions.pdf
cause I think there's something wrong with this reviewer.. or is it accurate?
btw is simplification different from minimizing from Sum of Minterms to Sum of Products?
Yes, it is the same.
Draw the truth table for both expressions, assuming that there are four input variables in both. The value of D will not play into the second truth table: values in cells with D=1 will match values in cells with D=0. In other words, you can think of the second expression as
F = A +B + C + (0)(D)
You will see that both tables match: the (A+B+C)(A+B+D') subexpression has zeros in ABCD= {0000, 0001, 0011}; (A+B+C) has zeros only at {0000, 0001}. Adding B'C patches zero at 0011 in the first subexpressions, so the results are equivalent.