Prolog findall existential quantifier - prolog

I have a problem with a problem in Prolog.
Here's some of the code I use.
has_same_elements([X|_],Y) :-
permutation(X,Xnew),
member(Xnew,Y), !.
has_same_elements([_|Tail],Y) :-
has_same_elements(Tail,Y).
This gets two lists of lists as input, and decides whether or not they contain lists with the same elements. E.g. [[1,2],[3,4]] has the same elements as [[2,1],[4,3]]. This works fine.
Now my findall:
findall(V, (verdeling2(S,Perm,V), \+X^(X\=V,verdeling2(S,Perm,X),has_same_elements(X,V))) ,Verd).
All that's important to know is that verdeling2/3 is a clause that returns different lists of lists (as mentioned above), and it's constructed from a permutation of [1,2,3,4,...]
Some different outputs of verdeling2/3 (according to the permutation as input) are:
V = [[[1, 2], [3, 4]]] ;
V = [[[2, 1], [3, 4]]] ;
V = [[[2, 3], [1, 4]]] ;
V = [[[2, 3], [4, 1]]] ;
V = [[[1, 3], [2, 4]]] ;
V = [[[3, 1], [2, 4]]] ;
V = [[[3, 2], [1, 4]]] ;
V = [[[3, 2], [4, 1]]] ;
V = [[[1, 3], [4, 2]]] ;
V = [[[3, 1], [4, 2]]] ;
V = [[[3, 4], [1, 2]]] ;
V = [[[3, 4], [2, 1]]] ;
V = [[[1, 2], [4, 3]]] ;
V = [[[2, 1], [4, 3]]] ;
V = [[[2, 4], [1, 3]]] ;
V = [[[2, 4], [3, 1]]] ;
V = [[[1, 4], [2, 3]]] ;
V = [[[4, 1], [2, 3]]] ;
V = [[[4, 2], [1, 3]]] ;
V = [[[4, 2], [3, 1]]] ;
V = [[[1, 4], [3, 2]]] ;
V = [[[4, 1], [3, 2]]] ;
V = [[[4, 3], [1, 2]]] ;
V = [[[4, 3], [2, 1]]] ;
Now I'd want something that gives me an overview of all lists that don't contain the same elements (using has_same_elements). I thought my use of findall should do the trick, but it returns full packet, instead of filtering the ones I don't want.

I am not assuming that you use some constraint logic programming language
or somesuch so that A\=B does more than only \+ A=B.
I guess the X\=V always fails so that the goals behind it are not executed,
and the negation \+ is always true.
The X\=V always fails, since X=V always succeeds, since X is a fresh
variable in your context.
Probably some reordering would help.
Best Regards

Related

Maximizing a boolean function of AND and XOR on paritions of set

Given a set of distinct positive integers S we need to partition a set in such a way that the following function is maximize. Let S1, S2, ... Sn be the parition. n can be atleast 2.
F(S1, S2, ..., Sn) = AND(XOR(S1), XOR(S2), ..., XOR(Sn)))
where, AND is bitwise AND operation and XOR is bitwise XOR operation
We need to print the all such partitions possible.
I have tried the exponential approach as shown below.
I am looking for a solution with lesser complexity.
This problem is part of a homework, so only provide the hint.
from functools import reduce
from collections import defaultdict
def partition(collection):
if len(collection) == 1:
yield [ collection ]
return
first = collection[0]
for smaller in partition(collection[1:]):
# insert `first` in each of the subpartition's subsets
for n, subset in enumerate(smaller):
yield smaller[:n] + [[ first ] + subset] + smaller[n+1:]
# put `first` in its own subset
yield [ [ first ] ] + smaller
# print("END OF THE LOOP")
x = 4
initialAssum = [2, 4, 8, 16]
something = initialAssum
def andxor(xs):
def xorlist(xs):
return reduce(lambda i, j: i ^ j, xs)
tmp = [xorlist(x) for x in xs]
return reduce(lambda i, j: i & j, tmp)
ans = defaultdict(list)
for n, p in enumerate(partition(something), 1):
r = andxor(p)
if len(p) > 1:
ans[r].append(p)
m = max(ans.keys())
for a in ans[m]:
print(a)
#print(a, len(a))
print(f'{m}')
INPUT: the set itself
OUTPUT: max value possible followed by the all the partitions producing it
INPUT:
[2, 3, 4]
OUTPUT:
2
[[4, 2], [3]]
[[2], [4, 3]]
INPUT:
[2, 4, 6, 8]
OUTPUT:
0
[[2], [4, 8, 16]]
[[2, 4], [8, 16]]
[[4], [2, 8, 16]]
[[2], [4], [8, 16]]
[[2, 4, 8], [16]]
[[4, 8], [2, 16]]
[[2], [4, 8], [16]]
[[2, 8], [4, 16]]
[[8], [2, 4, 16]]
[[2], [8], [4, 16]]
[[2, 4], [8], [16]]
[[4], [2, 8], [16]]
[[4], [8], [2, 16]]
[[2], [4], [8], [16]]
This problem is part of a homework, so only provide the hint.
Hint: if we consider each bit separately from the highest to lowest, we can consider bit k as being set in the result if and only if that bit can appear an odd number of times in each part of the partition.

matrixflip(m,d) where m is the matrix and d can be either h or v which are horizontal and vertical respectively

I am trying to write a python code for function which should return the matrix flipped horizontally and vertically
Am new to python
def matrixflip(myl,'v'):
output = list(myl[::-1])
return output
myl = [[1,2],[3,4]]
myl
[[1, 2], [3, 4]]
matrixflip(myl,'h')
[[2, 1], [4, 3]]
myl
[[1, 2], [3, 4]]
matrixflip(myl,'v')
[[3, 4], [1, 2]]
myl
[[1, 2], [3, 4]]
import copy
def matrixflip(l,char):
myl = copy.deepcopy(l)
if char == 'h':
for i in range(len(myll)):
myl[i].reverse()
if char == 'v':
i,j = 0, len(myl)-1
while(i<j):
myl[i], myl[j] = myl[j], myl[i]
i+=1
j-=1
return(myl)
Copy is used because original matrix value changed.
So don't change original list.

Creating a list of Domino

I'm trying to get a sorted list of Domino with a list of Domino
My code currently looks like:
listdomino(_,[],[],[]).
listdomino([I,J],M,Start,Fin):-
(( member([J,K],M),
delete(M,[J,K],M2),
append([[J,K]],Fin1,Fin),
listdomino([I,K],M2,Start,Fin1)
)
;
( member([K,I],M),
delete(M,[K,I],M2),
append(Start1,[[K,I]],Start),
listdomino([K,J],M2,Start1,Fin)
)
).
listdominoSorted(X,M,Out):-
append(Start,[X],K),
append(K,Fin,Out),
listdomino(X,M,Start,Fin).
Actual outcome:
?- listdominoSorted([1,2],[[2,1],[2,2]],L).
L = [[1, 2], [2, 2], [2, 1]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 2], [2, 1], [1, 2]] ;
The program returns [[2, 1], [1, 2], [2, 2]] twice
and doesn't exit after that.
Desired outcome:
?- listdominoSorted([1,2],[[2,1],[2,2]],L).
L = [[1, 2], [2, 2], [2, 1]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 2], [2, 1], [1, 2]] ;
false
How can I solve this problem?
I looked at your code for a minute or two but after seeing the use of delete/3 the warning bells went off and I looked at other examples. While this related answer does not answer your question, the statement
I suggest instead to have a quick check for validity, and let Prolog work out the insertion points.
lead me to trying a generate and test methodology for which Prolog is well suited.
First the test part:
No dominoes are valid.
domino_test([]).
One domino is valid.
domino_test([[_,_]]).
When ever two dominoes share the same counts (D_1) they are valid.
This is recursively valid.
domino_test([[_,D_1],[D_1,D_2]|T]) :-
domino_test([[D_1,D_2]|T]).
Next to generate the values.
This is really just a permutation of the dominoes.
?- permutation([[1,2],[2,1],[2,2]],P).
P = [[1, 2], [2, 1], [2, 2]] ;
P = [[1, 2], [2, 2], [2, 1]] ;
P = [[2, 1], [1, 2], [2, 2]] ;
P = [[2, 1], [2, 2], [1, 2]] ;
P = [[2, 2], [1, 2], [2, 1]] ;
P = [[2, 2], [2, 1], [1, 2]] ;
false.
Putting the permutation with the test in one predicates gives:
list_domino(L,P) :-
permutation(L,P),
domino_test(P).
All of the code
domino_test([]).
domino_test([[_,_]]).
domino_test([[_,D_1],[D_1,D_2]|T]) :-
domino_test([[D_1,D_2]|T]).
list_domino(L,P) :-
permutation(L,P),
domino_test(P).
Example:
?- list_domino([[1,2],[2,1],[2,2]],P).
P = [[1, 2], [2, 2], [2, 1]] ;
P = [[2, 1], [1, 2], [2, 2]] ;
P = [[2, 2], [2, 1], [1, 2]] ;
false.
I suspect your given test case is a simple case and there needs to be a modification to this, but I will let you check it and see.

Why "..." appears in my answer of matrix in Prolog

I made a little code for creating a matrix of coordinates (like a chessboard), it's the following:
createMatrix(N,M,R) :- creaMatriu(N,M,A), reversed(R,A).
creaMatriu(N,0,[T]) :- creafila(N,0,T),!.
creaMatriu(N,M,[T|C]) :- creafila(N,M,T), M1 is M-1, creaMatriu(N,M1,C).
creafila(0,M,[[M,0]]):-!.
creafila(N,M,[[M,N]|C]) :-N1 is N-1,creafila(N1,M,C).
reversed(A, B) :- reversed(B, [], A).
reversed([A|B], C, D) :- reverse(N,A),reversed(B, [N|C], D).
reversed([], A, A).
The first time I executed it went well, but when i incremented the dimensions of the matrix, the "dots" at the end of the matrix begin to appear incrementing one coordinate as the dimension rises, as like this:
?- createMatrix(1,1,R).
R = [[[0, 0], [0, 1]], [[1, 0], [1, 1]]] .
?- createMatrix(2,1,R).
R = [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]] .
?- createMatrix(2,2,R).
R = [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]], [[2, 0], [2, 1], [2, 2]]] .
?- createMatrix(3,2,R).
R = [[[0, 0], [0, 1], [0, 2], [0, 3]], [[1, 0], [1, 1], [1, 2], [1, 3]], [[2, 0], [2, 1], [2, 2], [2, 3]]] .
?- createMatrix(3,3,R).
R = [[[0, 0], [0, 1], [0, 2], [0, 3]], [[1, 0], [1, 1], [1, 2], [1, 3]], [[2, 0], [2, 1], [2, 2], [2, 3]], [[3, 0], [3, 1], [3, 2], [3|...]]] .
?- createMatrix(4,3,R).
R = [[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]], [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4]], [[2, 0], [2, 1], [2, 2], [2, 3], [2|...]], [[3, 0], [3, 1], [3, 2], [3|...], [...|...]]] .
?- createMatrix(4,4,R).
R = [[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]], [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4]], [[2, 0], [2, 1], [2, 2], [2, 3], [2|...]], [[3, 0], [3, 1], [3, 2], [3|...], [...|...]], [[4, 0], [4, 1], [4|...], [...|...]|...]] .
Anyone have any clue why this happens?
Thank you!
By default, the toplevel loop of SWI prints terms up to depth 10. Deeper parts are replaced by ... You can extend that depth or remove that limit by setting the depth to 0.
?- length(L,10).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I|...].
?- current_prolog_flag(toplevel_print_options,V).
V = [quoted(true),portray(true),max_depth(10),spacing(next_argument)].
?- set_prolog_flag(toplevel_print_options, [quoted(true), portray(true), max_depth(0), spacing(next_argument)]).
true.
?- length(L,10).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J].
— update: in newer versions of SWI, another flag must be changed:
?- current_prolog_flag(T,V), atom_concat(_,options,T).
T = answer_write_options,
V = [quoted(true),portray(true),max_depth(10),spacing(next_argument)]
; true.
?- set_prolog_flag(answer_write_options, [quoted(true), portray(true), max_depth(0), spacing(next_argument)]).
true.

Fill sparse array

I have a sparse array, for example:
rare = [[0,1], [2,3], [4,5], [7,8]]
I want to plot a chart with these data, each pair are point coordinates.
As you can see I don't have points for x=1, x=3 , x=5, x=6
I want to fill the array with the previous values, so for the above example I will get:
filled = [[0,1], [1,1], [2,3], [3,3], [4,5], [5,5], [6,5], [7,8]
As you can see, for calculating the y value, I simply take the last y value I used.
What is the best aproach to accomplish this ?
Range.new(*rare.transpose.first.sort.values_at(0,-1)).inject([]){|a,i|
a<<[i, Hash[rare][i] || a.last.last]
}
Step-by-step explanation:
rare.transpose.first.sort.values_at(0,-1) finds min and max x ([0,7] in your example)
Range.new() makes a range out of it (0..7)
inject iterates through the range and for every x returns pair [x,y], where y is:
y from input array, where defined
y from previously evaluated pair, where not
Note: here are some other ways of finding min and max x:
[:min,:max].map{|m| Hash[rare].keys.send m}
rare.map{|el| el.first}.minmax # Ruby 1.9, by steenslag
rare = [[0,1], [2,3], [4,5], [7,8]]
filled = rare.inject([]) do |filled, point|
extras = if filled.empty?
[]
else
(filled.last[0] + 1 ... point[0]).collect do |x|
[x, filled.last[1]]
end
end
filled + extras + [point]
end
p filled
# => [[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]
An inject solution:
filled = rare.inject([]) do |filled_acc, (pair_x, pair_y)|
padded_pairs = unless filled_acc.empty?
last_x, last_y = filled_acc.last
(last_x+1...pair_x).map { |x| [x, last_y] }
end || []
filled_acc + padded_pairs + [[pair_x, pair_y]]
end
More about Enumerable#inject and functional programming with Ruby here.
irb(main):001:0> rare = [[0,1], [2,3], [4,5], [7,8]]
=> [[0, 1], [2, 3], [4, 5], [7, 8]]
irb(main):002:0> r=rare.transpose
=> [[0, 2, 4, 7], [1, 3, 5, 8]]
irb(main):003:0> iv = (r[0][0]..r[0][-1]).to_a.select {|w| !r[0].include?(w) }
=> [1, 3, 5, 6]
irb(main):004:0> r[1][-1]=r[1][-2]
=> 5
irb(main):005:0> p (iv.zip(r[1]) + rare).sort
[[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]
=> [[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]

Resources