1

I'm trying to create 5 marriages, given 5 women and 5 man and their preferences to each other.

homem(miguel).
homem(joao).
homem(pedro).
homem(marco).
homem(carlos).

mulher(maria).
mulher(paula).
mulher(carla).
mulher(cristina).
mulher(ana).

all the marriages are stable (it is unstable if 2 person outside the marriage prefer each other more than their spouses), and I have their preferences to each other by ranks:

pref(miguel,paula,5).
pref(miguel,ana,4).
pref(miguel,maria,3).
pref(miguel,carla,2).
pref(miguel,cristina,1).

pref(maria,carlos,5).
pref(maria,miguel,4).
pref(maria,marco,3).
pref(maria,joao,2).
pref(maria,pedro,1).

pref(joao,maria,5).
pref(joao,paula,4).
pref(joao,carla,3).
pref(joao,cristina,2).
pref(joao,ana,1).

pref(paula,marco,5).
pref(paula,carlos,4).
pref(paula,joao,3).
pref(paula,miguel,2).
pref(paula,pedro,1).

pref(pedro,paula,5).
pref(pedro,carla,4).
pref(pedro,ana,3).
pref(pedro,cristina,2).
pref(pedro,maria,1).

pref(carla,miguel,5).
pref(carla,marco,4).
pref(carla,joao,3).
pref(carla,pedro,2).
pref(carla,carlos,1).

pref(marco,maria,5).
pref(marco,carla,4).
pref(marco,paula,3).
pref(marco,cristina,2).
pref(marco,ana,1).

pref(cristina,pedro,5).
pref(cristina,joao,4).
pref(cristina,marco,3).
pref(cristina,miguel,2).
pref(cristina,carlos,1).

pref(carlos,ana,5).
pref(carlos,carla,4).
pref(carlos,paula,3).
pref(carlos,maria,2).
pref(carlos,cristina,1).

pref(ana,marco,5).
pref(ana,joao,4).
pref(ana,pedro,3).
pref(ana,carlos,2).
pref(ana,miguel,1).
casamento(1..5). 

% every person belongs to one group only. 
1{in(H,M): casamento(C)}1 :- homem(H), mulher(M).

:- homem(H1), mulher(M1), homem(H2), mulher(M2), 
      pref(H1,M2,P1),pref(H1,M1,P2), P1>P2,
      pref(M2,H1,P3), pref(M2,H2,P4); P3>P4.

but this does not work and I don't know why.

logi-kal
  • 7,107
  • 6
  • 31
  • 43

1 Answers1

0

Problem 1

The rule

1{in(H,M): casamento(C)}1 :- homem(H), mulher(M).

doesn't mean that "every person belongs to one group only", but that "every pair of man and woman belongs to exactly one marriage. This is equivalent to say that every man is married with every woman.

Instead, you should express the contrary: every marriage should "generate" exactly one pair of people:

1{in(H,M,C): homem(H), mulher(M)}1 :- casamento(C) .

But this doesn't prevent a men (or woman) to belong to two different marriages. So you shoul also add:

:- in(H,M1,C1), in(H,M2,C2), C1!=C2 .
:- in(H1,M,C1), in(H2,M,C2), C1!=C2 .

Problem 2

Moreover, in your constraint you're considering every pair of people (not every pair of married people!). So you should replace homem(H1), mulher(M1), homem(H2), mulher(M2) with in(H1,M1,C1), in(H2,M2,C2).

Fixed code

casamento(1..5) .

1{in(H,M,C): homem(H), mulher(M)}1 :- casamento(C) .
:- in(H,M1,C1), in(H,M2,C2), C1!=C2 .
:- in(H1,M,C1), in(H2,M,C2), C1!=C2 .

:- in(H1,M1,C1), in(H2,M2,C2), 
   pref(H1,M2,P1), pref(H1,M1,P2), P1>P2,
   pref(M2,H1,P3), pref(M2,H2,P4), P3>P4 .

This program (plus the EDB in your example) generates the following marriages:

in(miguel,carla,2) in(marco,paula,3) in(joao,cristina,1) in(carlos,maria,4) in(pedro,ana,5)

Optional

If you don't want to hardcode the 5 and make it work for any number of people in input, you can dynamically count the number of women (or men, assuming that it's the same).

So you can replace casamento(1..N). with:

casamento(1..N) :- N = #count{ X : mulher(X) } .
logi-kal
  • 7,107
  • 6
  • 31
  • 43