I am trying to solve a puzzle in prolog and i made only a part of it, i can't figure out how to finish it. This is the problem:
Consider four men with last names of Baker, Carpenter, Miller, and Farmer. Assume that the four professions represented by this group include a baker, a carpenter, a miller, and a farmer. Assume further that each person has a profession that does not correspond to their last name.
Each of these four men has a son. The four sons have professions of baker, carpenter, miller, and farmer. Assume again that each person has a profession that does not correspond to their last name.
Assume that we also know the following facts: No son has the same profession as his father. Baker has the same profession as the carpenter's son. The farmer's son is a baker.
The part I cannot figure out how to implement is:
Baker has the same profession as the carpenter's son.
The farmer's son is a baker.
This is my code for the part of the problem that i made so far:
DOMAINS
father = father(lastname,profession)
son = son(lastname2,profession2)
list2 = son*
list = father*
lastname = string
profession = string
lastname2 = string
profession2 = string
PREDICATES
nondeterm member(father, list)
nondeterm member(son,list2)
solution
CLAUSES
member(Item, [Item|_]).
member(Item,[_|Tail]) :- member(Item,Tail).
solution:-
List = [father("Baker" , BakerFatherJob),
father("Carpenter" , CarpenterFatherJob),
father("Miller" , MillerFatherJob),
father("Farmer",FarmerFatherJob)],
List2 = [son("Baker" , BakerSonJob),
son("Carpenter" , CarpenterSonJob),
son("Miller" , MillerSonJob),
son("Farmer",FarmerSonJob)],
member(father(_, "Baker"), List),
member(father(_, "Carpenter"), List),
member(father(_, "Miller"), List),
member(father(_, "Farmer"), List),
member(son(_, "Baker"), List2),
member(son(_, "Carpenter"), List2),
member(son(_, "Miller"), List2),
member(son(_, "Farmer"), List2),
BakerFatherJob<>BakerSonJob,
CarpenterFatherJob<>CarpenterSonJob,
MillerFatherJob<>MillerSonJob,
FarmerFatherJob<>FarmerSonJob,
BakerFatherJob <> "Baker",
CarpenterFatherJob <> "Carpenter",
MillerFatherJob <> "Miller",
FarmerFatherJob <> "Farmer",
BakerSonJob <> "Baker",
CarpenterSonJob <> "Carpenter",
MillerSonJob <> "Miller",
FarmerSonJob <> "Farmer",
write("Father Baker has job ", BakerFatherJob),nl,
write("Father Carpenter has job ", CarpenterFatherJob), nl,
write("Father Miller has job ", MillerFatherJob),nl,
write("Father Farmer has job ", FarmerFatherJob),nl,
write(" "), nl,
write("Son Baker has job ", BakerSonJob),nl,
write("Son Carpenter has job ", CarpenterSonJob), nl,
write("Son Miller has job ", MillerSonJob),nl,
write("Son Farmer has job ", FarmerSonJob),nl,
write(" "), nl,
fail.
solution:-
write(" ALL SOLUTIONS HAVE BEEN FOUND")
Right now you're naming the people's jobs,
solution:-
List = [father("Baker" , BakerFatherJob),
father("Carpenter" , CarpenterFatherJob),
father("Miller" , MillerFatherJob),
father("Farmer", FarmerFatherJob)],
List2 = [son("Baker" , BakerSonJob),
son("Carpenter" , CarpenterSonJob),
son("Miller" , MillerSonJob),
son("Farmer", FarmerSonJob)],
Amend your code to also name the jobs' persons:
member( father( OlderBakerName, "Baker"), List),
member( father( OlderCarpenterName, "Carpenter"), List),
member( father( OlderMillerName, "Miller"), List),
member( father( OlderFarmerName, "Farmer"), List),
member( son( YongerBakerName, "Baker"), List2),
member( son( YongerCarpenterName, "Carpenter"), List2),
member( son( YongerMillerName, "Miller"), List2),
member( son( YongerFarmerName, "Farmer"), List2),
At this point all the jobs and people's names are assigned. Now you can write down your missing rules:
Baker has the same profession as the carpenter's son.
"Baker" here is a name (or else we get a contradiction with the next rule). And he must be a father (why?), so his job is BakerFatherJob
. The carpenter's name (again, must be a father -- why?) is not "Carpenter" -- that's forbidden by the rules. We named him OlderCarpenterName
. His son has the same name:
member( son( ... , JobX ), List.... ),
and we know that the two jobs are the same:
JobX = ... ,
The farmer's son is a baker.
Now you can do this, too.
The lesson: name your stuff; use descriptive names to ease the cognitive load.