Implementing a relation on a data structure [closed] - prolog

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have the following simple Prolog program that, through the use of data structure, represents a family composed of husband, wife and children list:
family(
person(bob, smith, date(7,may,1968), 30000),
person(ann, smith, date(18,july,1970), 32000),
[person(dave, smith, date(1,june,1984), 0),
person(edna, smith, date(25,may,1990), 0)]
).
family(
person(mario, rossi, date(7,may,1968), 30000),
person(lucia, verdi, date(18,july,1970), 32000),
[person(luca, rossi, date(1,june,1984), 5000),
person(maria, rossi, date(25,may,1990), 0),
person(paolo, rossi, data(16, april, 1980), 10000)]
).
family(
person(carlo, bianchi, date(7,may,1968), 30000),
person(flavia, blabla, date(18,july,1970), 32000),
[person(figlio1, bianchi, date(1,june,1984), 0),
person(figlio2, bianchi, date(25,may,2001), 0),
person(figlio3, bianchi, data(16, april, 1980), 10000),
person(figlio4, bianchi, data(10, april, 1978), 20000)]
).
family(
person(no, no, date(7,may,1968), 30000),
person(no, no, date(18,july,1970), 32000),
[]
).
/* Regola che mostra i mariti: */
husband(X) :- family(X,_,_).
/* Regola che mostra l mogli: */
wife(X) :- family(_,X,_).
/* Regola che mostra i figli:
X è figlio se in una famiglia c'è una lista di figli e se X appartiene
alla lista dei figli: */
child(X) :- family(_,_,Children),
member(X,Children).
This is very simple. By some facts I represent some family and I have some rule to perform some query (to obtain the husbands, the wifes, if X is a child in a family, if a person exist in a family, the salary of a person and the date of birth of a person)
OK, until now I have no problem.
Then I have the following exercise related to the previous program: Write a rule that calculates the total salary of all the children in each family
So I have to calculate a value that I have call ChildrenIncoming that represents the sum of the salary (the last value in the person data structure representing a child in a family data structure) of all the children belonging to a specific family
I am finding many problems to implement this functionality.
I am started from easier task (for example retrieve the salary of an husband) like this:
husbandIncoming(HSurname, HIncoming) :- husband(HSurname), % Seleziona un cognome
salary(HSurname, HIncoming).
I have try to calculate the ChildrenIncoming value trying to do something like it (that it is incomplete and don't work):
childrenList(Husband,ChildrenList) :- family(Husband,_,ChildrenList).
/* If ChildrenList is empty: ChildrenIncomung value 0 */
childrenIncoming(Husband,[],0).
childrenIncoming(Husband,ChildrenList,ChildrenIncoming) :-
childrenList(Husband,ChildrenList),
ChildrenList = [Head|Tail],
childrenIncoming(Husband,Tail,TailIncoming),
salary(Head, ChildrenIncoming).
first thing is that I identify a family by the husband so I can retrieve the ChildrenList using the childrenList rule (this rule works well).
Then I would calculate the sum of all the salary of all person that are inside this ChildreList and to do that I introduced the relation childrenIncoming that have to calculate it.
This relation start by the fact that simply say:
childrenIncoming(Husband,[],0).
If a family (having Husband as paterfamilias) have empty children list, then the total incoming of the children is 0.
Then I have introduce a rule (wrong) that should calculate this value in the case of non-empty children list.
The reasoning behind this rule is that:
1) A not empty children list contains person.
2) a non-empty list can be divided into an Head of the list (that is a person) and a Tail sublist (a list of person)
3) the head is a person and have a salary
4) the tail contains persons and each one have a salary
But I don't know how mix these ideas in the right way to obtain the desired result (the value of the total incoming of all person in the children list)
I don't know if this kind or reasoning is good or if I am wrong from the beginning.

If you add these predicates to family/3 facts
husband(family(H, W, C), P) :- family(H, W, C), H = person(P,_,_,_).
children(family(_, _, C), C).
income(P, I) :- P = person(_,_,_,I).
childrenIncoming(Family, ChildrenIncoming) :-
children(Family, Children),
sum_income(Children, 0, ChildrenIncoming).
sum_income([], Sum, Sum).
sum_income([C|Children], SoFar, Sum) :-
income(C, I),
Updated is I + SoFar,
sum_income(Children, Updated, Sum).
with this query you get
?- husband(F, mario), childrenIncoming(F,I).
F = family(person(mario, rossi, date(7, may, 1968), 30000), person(lucia, verdi, date(18, july, 1970), 32000), [person(luca, rossi, date(1, june, 1984), 5000), person(maria, rossi, date(25, may, 1990), 0), person(paolo, rossi, data(16, april, 1980), 10000)]),
I = 15000 .

I also create this one that calculate the total incoming of all components of a specific family:
/* FATTO (CASO BASE): Se la lista dei figli è una lista vuota, non ci
sono figli quindi la somma dei redditi dei figli è 0
*/
somma([],0).
/* REGOLA (CASO GENERALE): La lista dei figli non è vuota quindi può essere
decomposta in un'HEAD (person(_,_,_,E) ed in una sottolista L.
SE è VERO che: il valore della somma di tutti gli elementi nella
sottolista L è S1 ed è VERO che il valore di S è S1+E allora è VERO
che la somma dei redditi nella lista [H|L] è S
*/
somma([person(_,_,_,E)|L],S):- somma(L,S1),
S is S1+E.
/* Una famiglia è identificata dal COGNOME DEL MARITO.
Il REDDITO TOTALE di una famiglia è la somma del reddito del marito +
reddito moglie + la somma dei redditi di tutti i figli nella lista
dei figli.
*/
reddito(C,R):- family(person(_,C,_,RP), person(_,_,_,RM), FIGLI),
somma(FIGLI,RF),
R is RF+RP+RM.
The comments are in italian but I think that looking the code is pretty simple understand what it means :-)

Related

Prolog: How to get oldest and youngest in bloodline

Let's say that I have a bloodline of male population Williams and Skywalker families as my knowledge base:
father(phil,tom, williams).
father(tom, bob, williams).
father(bob, robert, williams).
father(robert, steve, williams).
father(anakin, luke, skywalker)
father(luke, finn, skywalker)
father(finn, andrew, skywalker)
father( andrew, charles, skywalker)
Which rule can I use to know the oldest and youngest in bloodline?
For example
?- oldestYoungest(skywalker,X,Y)
should return
X = anakin
Y = charles
This works with your Knowledge Base (KB) looking the way it does now.
youngest(LastName, Son) :-
father(_, Son, LastName),
\+father(Son, _, LastName).
oldest(LastName, Father) :-
father(Father, _, LastName),
\+father(_, Father, LastName).
oldestYoungest(LastName, Oldest, Youngest) :-
youngest(LastName, Youngest),
oldest(LastName, Oldest).
You should note that Prolog variables are upper-case and constants (or facts) are lower-case.
Technically, this answer finds oldest as the person with no father in the KB and the youngest and the person with no son in the KB. It works because your KB is defined that way.

Directed graphs in prolog

I have a graph that I am creating rules on. owes money graph
I have created rules that shows who owes money to who
owes(alice,5,charlie).
owes(alice,20,bob).
owes(bob,10,charlie).
I have created rules that display who owes someone under a certain amount or over
owesOver10(X,Y) :-owes(X,Y,Z),(Y>=10).
owesUnder10(X,Y) :-owes(X,Y,Z),(Y<10).
however know I need to write a rule that shows how much money a person owes in total so for instance it should display 25 for alice, and 10 for bob.
I propose the use of findall/3 to get a list of all owes and a simple sumList/2 to get the sum of the values.
By example
listSum([], 0).
listSum([H | T], S0) :-
listSum(T, S1),
S0 is S1 + H.
totOwes(X, S) :-
findall(Y, owes(X, Y, _), L),
listSum(L, S).
Calling totOwes(alice, S), I get that S is unified with 25; for bob with 10 and for charlie with 0.

Somebody could help me with this little program in prolog?

When I run my program with this sentence:
| ?- constraints(C).
and the result is:
C = [espacio(chuck,brenda,lewis,cafe,treintayuno),
espacio(bill,mary,tread,rojo,veinteynueve),
espacio(steve,cindy,branch,negra,cuarentaytres),
espacio(tom,laura,forrest,azul,treintaycinco)|_A] ?
The result is fine but at the end is there an "|A" and I don't know what is wrong???
It is my code:
/*
Cuatro parejas deciden ir a acampar a la selva del estado un fin de semana.
Cada pareja viajo en una van diferente y cada una eligio un espacio de
campo separado. Todos los sitios para acampar estan etiquetados con un
numero y mientras estan en la misma area los sitios no se juntan entre si.
Determina el nombre completo de cada pareja, color de van y numero de su
espacio de campo.
TRADUCCION
1.- BIll quie no esta casado con Laura, no manejo una Van Negra
2.- Chuck y su esposa Brenda no acamparon en el espacio #35. El apellido de
Breanda no es Forrest
3.- La pareja Lewis quien manejo una van Cafe, acamparon en el espacio 31
4.- Tom acampo en un espacio mas bajo del que acampo Cindy pero mas alto
que la pareja que manejo una Van Roja.
5.- Tom no esta casado con Mary Tread. Steve Branch no maneja una van azul.
6.- La pareja que maneja la van negra acampo en el espacio #43
ORIGINAL
1. Bill, who is not married to Laura, didn't drive a black van.
2. Chuck and his wife Brenda were not camped in space #35. Brenda's last
name is not
Forrest.
3. The Lewis couple, who drove a tan van, camped in space #31.
4. Tom camped in a space numbered lower than the one Cindy camped in but
higher than the
couple who drove in the red van did.
5. Tom isn't married to Mary Tread. Steve Branch didn't drive a blue van.
6. The couple driving the black van camped in space #43.
*/
use_module( library(basics)).
use_module(library(lists)).
% UN CAMPAMENTO ES UNA LISTA DE 5 ESPACIOS; CADA ESPACIO TIENE UNA PAREJA
(HOMBRE Y MUJER Y APELLIDO) UNA VAN Y UN NUMERO DE ESPACIO.
campamento([espacio(_,_,_,_,_),
espacio(_,_,_,_,_),
espacio(_,_,_,_,_),
espacio(_,_,_,_,_)]).
% De acuerdo a las sentencias previas podemos establecer lo siguiente:
constraints( Campamento ):-
member(espacio(chuck,brenda,_,_,_), Campamento), % 2)
member(espacio(_,_,lewis,cafe,treintayuno), Campamento), % 3)
member(espacio(_,mary,tread,_,_), Campamento), % 5)
member(espacio(_,_,_,rojo,veinteynueve), Campamento), % implicito
)
member(espacio(_,_,_,negra,cuarentaytres), Campamento), % 6)
member(espacio(_,_,_,azul,treintaycinco), Campamento), % implicito
)
member(espacio(bill,_,_,_,veinteynueve), Campamento), % implicito
)
member(espacio(steve,cindy,branch,_,_), Campamento), % implicito )
member(espacio(_,cindy,_,_,cuarentaytres), Campamento), %
implicito )
member(espacio(tom,laura,forrest,_,_), Campamento). % implicito )
% member(espacio(tom,_,_,blue,_), Campamento). % implicito )
% member(espacio(_,mary,_,red,_), Campamento). % implicito )
append([X|Y],Z,[X|W]) :- append(Y,Z,W).
append([],X,X).
member(X,[X|_]).
member(X,[_|T]) :- member(X,T).
% perm2(X,Y, X,Y).
% perm2(X,Y, Y,X).
/*member(X,[X|T]).
member(X,[H|T]) :- member(X,T).*/
(Your program has several errors: In particular use_module(xx) must be prefixed with :-)
constraints/1 essentially looks like this:
constraints(L) :-
member(a, L),
member(b, L),
member(c, L),
member(d, L).
So you demand that a, b, c, and d are elements of L. But nowhere do you state how long the list should be. You can observe this by looking at alternate answers pressing ;Return.
?- constraints(L).
L = [a, b, c, d|_A]
; L = [a, b, c, _A, d|_B]
; L = [a, b, c, _A, _B, d|_C]
; false.
To fix this, add length(L, 4) at the beginning, before any goal member/2.
OK, it is my Friend!!!
Thanks very much for all you help!!! it is the code like how i tell you:
/*
ORIGINAL
1. Bill, who is not married to Laura, didn't drive a black van.
2. Chuck and his wife Brenda were not camped in space #35. Brenda's last name is not
Forrest.
3. The Lewis couple, who drove a tan van, camped in space #31.
4. Tom camped in a space numbered lower than the one Cindy camped in but higher than the
couple who drove in the red van did.
5. Tom isn't married to Mary Tread. Steve Branch didn't drive a blue van.
6. The couple driving the black van camped in space #43.
*/
%:- use_module( library(basics)).
:- use_module(library(lists)).
campamento([espacio(_,_,_,_,_),
espacio(_,_,_,_,_),
espacio(_,_,_,_,_),
espacio(_,_,_,_,_)]).
constraints( Campamento ):-
length(Campamento, 4),
% campamento(Campamento),
member(espacio(chuck,brenda,_,_,_), Campamento), % 2)
member(espacio(_,_,lewis,cafe,treintayuno), Campamento), % 3)
member(espacio(_,mary,tread,_,_), Campamento), % 5)
member(espacio(_,_,_,rojo,veinteynueve), Campamento), % implicito
member(espacio(_,_,_,negra,cuarentaytres), Campamento), % 6)
member(espacio(_,_,_,azul,treintaycinco), Campamento), % implicito
member(espacio(bill,_,_,_,veinteynueve), Campamento), % Implicito
member(espacio(steve,cindy,branch,_,_), Campamento), % implicito
member(espacio(_,cindy,_,_,cuarentaytres), Campamento), % implicito
member(espacio(tom,laura,forrest,_,_), Campamento). % implicito
append([],X,X).
append([X|Y],Z,[X|W]) :- append(Y,Z,W).
member(X,[X|T]).
member(X,[H|T]) :- member(X,T).
perm2(X,Y, X,Y).
perm2(X,Y, Y,X).

Use of =.. predicate to perform symbolic manipulation of furmulas in Prolog

I am learning Prolog for an universitary university exam using SWI Prolog and I have some doubts about how it work this exercise that use the univ =.. =.. predicate to perform symbolic manipulation of furmulas formulas where a frequent operation is to substituite substitute some subexpression by another expression.
It is perform defining the following relation:
substituite(SubTerm, Term, SubTerm1, Term1)
that it is TRUE if Term1 rappresent represents Term expression in which all the occurrences of SubTerm are substituited by SubTerm1.
For example if I have:
substituite(sin(x), 2*(sin(x)), t, F).
Then: F = 2*t*f(t) because all the sin(x) occurrences are substituited by t
This is the solution (founbd on Bratko book) but I am not so sure about my interpretation:
% substitute( Subterm, Term, Subterm1, Term1)
% Term1 is Term with all occurrences (by matching)
% of Subterm are replaced by Subterm1.
% Test: ?- substitute( b, f(a,b,c), e, F).
% Test: ?- substitute( b, f(a,X,c), e, F).
% Test: ?- substitute( b, f(a,X,Y), e, F).
% Test: ?- substitute( a+b, f( a, A+B), v, F).
% Test: ?- substitute(b,B,e,F).
% Test: ?- substitute(b,b,e,F).
% Test: ?- substitute(b,a,e,F).
% Logic, there are three cases:
% If Subterm = Term then Term1 = Subterm1
% otherwise if Term is 'atomic' (not a structure)
% then Term1 = Term (nothing to be substituted)
% otherwise the substitution is to be carried
% out on the arguments of Term.
/* Case 1: SubTerm = Term --> SubTerm1 = Term1 */
substitute(Term, Term, Term1, Term1) :- !.
% Case 2: Se Term è atomico non c'è niente da sostituire
substitute( _, Term, _, Term) :- atomic(Term), !.
/* Case 3:
substitute(Sub, Term, Sub1, Term1) :-
Term =.. [F|Args], % Term è composto da: F è il FUNTORE PRINCIPALE ed Args è la lista dei suoi argomenti
substlist(Sub, Args, Sub1, Args1), % Sostituisce Sub1 al posto di Sub nella lista degli argomenti Args generando Args1
Term1 =.. [F|Args1]. % Term1 è dato dal FUNTORE PRINCIPALE F e dalla nuova lista degli argomenti Args1
/* sublist: sostituisce all'interno della lista degli argomenti: */
substlist(_, [], _, []).
substlist(Sub, [Term|Terms], Sub1, [Term1|Terms1]) :-
/* L'elemento in testa Term1 corrisponde all'eventuale sostituzione */
substitute(Sub, Term, Sub1, Term1),
/* Il problema è già risolto per le sottoliste e Terms1 rappresenta la sottolista Terms in cui tutte le occorrenze di Sub
sono già state sostituite con Sub1:
*/
substlist(Sub, Terms, Sub1, Terms1).
The first rule rappresent represents the particular case in which SubTerm = Term so the final Term1=SubTerm1 (because I substituite substitute whole term)
The second rule rappresent represents the particular case in which Term is an atom so, regardless of the values ​​of SubTerm and SubTerm1, I do not perform any substitution
I think that up to here it is simple and my reasoning it is correct...next to it begin the more difficult part and I am not so sure...
The rule:
substitute(Sub, Term, Sub1, Term1) :-
Term =.. [F|Args],
substlist(Sub, Args, Sub1, Args1),
Term1 =.. [F|Args1].
rappresent represents a generic case in which I have an expression rappresented represented by Term, its possible subexpression rappresented represented by Sub, a new subexpression Sub1 that eventually should be substituted when you meet an occurrence of Sub and the expression Term1 that rappresent Term expression in which all the occurrences of SubTerm are substituited by SubTerm1.
So I can read it declaratively in this whay way:
It is TRUE that Term1 rappresent represents Term expression in which all the occurrences of SubTerm are substituited by SubTerm1 if there are TRUE the following facts:
1) The original expression Term can be decomposed in a list that have in the head its main functor F (the first operator executed in the expression evalutation) and later a sublist Args that rappresent the arguments of this functor F (I think that, in some case, Args can contain also other functor that, in this computational step, don't are the main functor...so in these case there are still some subproblem to solve)
2) It is true that substlist(Sub, Args, Sub1, Args1) that means that this is true that Args1 rappresent Args in which all the argument equals to Sub subexpression are replaced by Sub1 subexpression.
3) Finally it must be true that the new Term1 is the result of the univ =.. predicate beetwen the main functor F and the new arguments list Args1 (I think that =.. recombine the main functor F with the new arguments list
To perfrom the substitution in the arguments list it is used the substlist relation that it is divided into:
A BASE CASE:
substlist(_, [], _, []).
that simply say: if there is nothing in the arguments list, there is nothing to replace
A GENERAL CASE:
substlist(Sub, [Term|Terms], Sub1, [Term1|Terms1]) :-
/* L'elemento in testa Term1 corrisponde all'eventuale sostituzione */
substitute(Sub, Term, Sub1, Term1),
/* Il problema è già risolto per le sottoliste e Terms1 rappresenta la sottolista Terms in cui tutte le occorrenze di Sub
sono già state sostituite con Sub1:
*/
substlist(Sub, Terms, Sub1, Terms1).
And this is the more difficult part to understand for me, I see it in the following way, declarative reading:
It is TRUE that [Term1|Terms1] rappresent the list of arguments [Term|Terms] in which all the Sub term are replaced by Sub1 if it is true that:
1) substitute(Sub, Term, Sub1, Term1): that means that it is TRUE that Term1 (the head of the new arguments list it is Term (the head of the old arguments list) in which if Term == Sub ---> Term1 == Sub1
2)substlist(Sub, Terms, Sub1, Terms1) that means all the subproblem are solved, I think that this is an important point because the argument list Term is the argument list of a current main functor F but can contain other sub functors inside it and each of these rappresent a subproblem that have to be solved befor perform the Sub-->Sub1 replacements in this step.
But I am not so sure about this last thing...
someone can help me to deeply understand it
Tnx
Andrea
Let me start by saying that it would be nice if you kept questions short and to the point. The whole idea of Stackoverflow is that questions and answers will be later useful to others, and writing good questions is a big part of this.
Moving on: All programming languages have some right to the claim that the actual source code of a program is the most clear, complete, and exhaustive explanation (to a human) of what the program does. Prolog definitely has a right to that claim. It takes a bit of getting used to, but soon a well-written predicate does tell more about the program logic than an often futile attempt to give a precise specification / definition in an inherently ambiguous natural language, be it English, Italian, or even German.
Now to your question...
What does =../2 do? We may look here, but, in a few words, we have f(a,b, ..., x) on the left side, and [f, a, b, ..., x] on the right side of it.
Assuming recursion, lists, matching and unification don't need to be explained here, the program you have extensively studied, commented in Italian, and thoroughly explained to us in English, does one simple thing: all occurrences of Subterm in Term are substituted by Subterm1 in Term1.
This is done:
by directly replacing simple terms (atoms) by matching
by breaking down complex terms (of the form f(Args)) into a list (using =..), and then applying the algorithm recursively on the simpler terms in that list (the elements of Args). Afterwords, the list is reassembled, using =.. again.
So if you have a nested term, you still get:
?- substitute(x, f( g( h(x,y,z), h(k,l,m) ), g(x,z) ), q, T).
T = f(g(h(q, y, z), h(k, l, m)), g(q, z)) ;
false.
The only slight difficulty one might encounter here is that substitute and substlist are mutually recursive. If this is giving you that much difficulty, one thing you can try and do is to remove all comments from the predicate definitions, fit the whole program on the screen at once (or print it out), and look at it and think about it until it makes sense. It works!

From 8-Queens solution to more generic n-Queens solution in Prolog

I am studying Prolog for an universitary exame and I have some problem with the following exercise.
I have the following classic solution of 8-Queens problem (and this is not a problem for me), Modifying this solution I have to create a new solution for the more generic n-Queens problem that handle a variable number of queens.
solution([]).
solution([X/Y|Others]) :- solution(Others),
member(Y,[1,2,3,4,5,6,7,8]),
noattack(X/Y, Others).
noattack(_,[]).
noattack(X/Y, [X1/Y1 | Others]) :-
Y =\= Y1, % Q e Q1 sono su righe diverse
% Q e Q1 sono su diagonali diverse:
Y1-Y =\= X1-X,
Y1-Y =\= X-X1,
% Q non attacca regine nella sottolista Others:
noattack( X/Y, Others).
% TEMPLATE DELLE SOLUZIONI: c'è una regina su ogni colonna:
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).
Ok, this program look pretty simple: I have a list of queen that have that they must not attack each other.
If the list of queen is empty there is not the possibility that a queen attack another queen in the list, so the empty list is a solution of the problem (it is the base case of the solution)
*If the list of queen is not empty I can divide it into [X/Y|Others] where X/Y rappresent position on the board of the first queen in the list *(the position is rappresentend by the couple (X,Y) where X is the column and Y the line)
So, it is TRUE that the list [X/Y|Others] is a SOLUTION of the problem if the following relations are true:
The sublist Others is itself a solution (Others don't contain queen that attack some other queen in the list)
Y belongs belongs to an integer value between 1 and 8 (because I have 8 line)
The first queen of the list don't attacck the others queens in the sublist Others
Then it is defined the noattack relation that specify when I can say that it is true that a queen don't attack another queen (this is pretty simple: they can't stay on the same line, on the same column, on the same diagonal)
Finally I have a solution template that simplify my life constraining the X value with value from 1 to 8 (because I know that 2 queens can't stay on the same columns...so every queen in the solution stay on a different column from all others queens)
So I think that the biggest problem it is on the line in which I specify the number of columns:
member(Y,[1,2,3,4,5,6,7,8])
and on the line in which I define the solution template:
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).
I have no idea about how to extend the previous solution to handle a variable number of queens.
seems easy, passing around the size:
solution(_, []).
solution(N, [X/Y|Others]) :-
solution(N, Others),
between(1, N, Y),
noattack(X/Y, Others).
noattack(_,[]).
noattack(X/Y, [X1/Y1 | Others]) :-
Y =\= Y1, % Q e Q1 sono su righe diverse
Y1-Y =\= X1-X, % Q e Q1 sono su diagonali diverse
Y1-Y =\= X-X1,
noattack( X/Y, Others). % Q non attacca regine nella sottolista Others
% TEMPLATE DELLE SOLUZIONI: c'è una regina su ogni colonna:
template(N, L) :-
findall(I/_, between(1,N,I), L).
test:
?- N=6, template(N, L), solution(N, L).
N = 6,
L = [1/5, 2/3, 3/1, 4/6, 5/4, 6/2] ;
N = 6,
L = [1/4, 2/1, 3/5, 4/2, 5/6, 6/3] ;
N = 6,
L = [1/3, 2/6, 3/2, 4/5, 5/1, 6/4] ;
N = 6,
L = [1/2, 2/4, 3/6, 4/1, 5/3, 6/5] ;
false.
(I should draw it to say if it's ok...)

Resources