Murder puzzle in ASP

620 Views Asked by At

So under the tag prolog I found this puzzle (original post) and I thought: this would be even better in ASP. So I put this here as a question for anyone who wants to solve a puzzle with me. I will answer this question as soon as I found a solution myself, and I would be happy to compare my code with yours. Thank you.

jean was killed on Tuesday; the only suspects are:

Luc, Paul, Alain, Bernard and Louis.

The rules to follow are:

  1. The murderer is somebody who has a motive to kill jean, who owns a gun, and who does not have an alibi for Tuesday.

  2. An alibi provided by a person who is not trustworthy is not accepted.

  3. Somebody has a motive to kill jean if he has a special interest in killing jean or he wants revenge.

  4. Somebody has a special interest in killing jean is he is the beneficiary of jean’s fortune, or if he owns money to jean, or if jean surprised him committing a crime.

Here are the facts established by the investigation:

Luc has an alibi for Tuesday given by Bernard

Paul has an alibi for Tuesday given by Bernard

Louis has an alibi for Tuesday given by Luc

Alain has an alibi for Thursday given by Luc

Alain is not a trustworthy person

Paul wants to take revenge on Jean

Luc wants to take revenge on Jean

Bernard is the beneficiary of Jean’s fortune

Jean is the beneficiary of Louis’s fortune

Louis owns money to Jean

Luc owns money to Jean

Jean has seen Alain committing a crime

Luc owns a gun

Louis owns a gun

Alain owns a gun

2

There are 2 best solutions below

2
On

I tried this problem , and and this is my solution . I hope it will help you and if does , so please click on check and rank solution.

alibi(luc,bernard,tuesday).
alibi(paul,bernard,tuesday).
alibi(louis,luc,tuesday).
alibi(alain,luc,thursday).
notrust(alain).
revenge(paul,jean).
revenge(luc,jean).
benefit(bernard,jean).
benefit(lean,louis).
owns(louis,jean).
owns(luc,jean).
crime_seen(alain,jean).
gun(luc).
gun(louis).
gun(alain).
special_interest(X,jean):- benefit(X,jean);owns(X,jean);crime_seen(X,jean).
true_alibi(X):- alibi(X,Y,tuesday), \+ notrust(Y).
motive(X,jean):- special_interest(X,jean);revenge(X,jean).
murderer(X,jean):- gun(X),motive(X,jean),\+ true_alibi(X).
solve(X):-murderer(X,jean).
0
On
person(luc; paul; alain; bernard; louis).

alibi(luc,tuesday,bernard).
alibi(paul,tuesday,bernard).
alibi(louis,tuesday,luc).
alibi(alain,thurday,luc).
ntw(alain).
revenge(paul,jean).
revenge(luc,jean).
beneficiary(bernard, jean).
beneficiary(jean, louis).
owns(louis,jean).
owns(luc,jean).
seen(jean,alain).
gun(luc;louis;alain).

{murderer(M):person(M)} == 1.
murderer(M) :- person(M), motiv(M,jean), gun(M), not validalibi(M,tuesday,_).
validalibi(M,D,A) :- alibi(M,D,A), tw(A).
{ntw(P);tw(P)} == 1:- person(P).
motiv(P,O) :- revenge(P,O).
motiv(P,O) :- interest(P,O).
interest(P,O) :- beneficiary(P,O).
interest(P,O) :- owns(P,O).
interest(P,O) :- seen(O,P).

#show tw/1.
#show murderer/1.

My solution assumes that there is only one murderer and every person is either trustworthy (tw/1) or not (ntw/1). The output is

Answer: 1
murderer(alain) tw(bernard) tw(luc) tw(paul)
Answer: 2
murderer(alain) tw(bernard) tw(luc) tw(paul) tw(louis)
Answer: 3
murderer(alain) tw(bernard) tw(luc)
Answer: 4
murderer(alain) tw(bernard) tw(luc) tw(louis)
SATISFIABLE

Which more or less states: if there is only one murderer then it is Alain and it does not matter if Paul or Louis are trustworthy.