Guess what game in Prolog

I am developing Guess Who? using prolog. The mechanism of the game is very simple. The player (in this case, the person) selects one person from among many possible, and the other player (computer) starts asking yes / no questions about some of the attributes of the person. In the end, given the answers, there will be only one person.

So far, I have managed to compile a set of rules and predicates so that a computer can guess a person based on questions asked. I have many suspects - these are people who can fit with the available clues.

suspect('Person 1') :- eyes(blue) , age(old) , gender(male). 

Predicates for attributes are defined so that they are true if the question about this attribute has not yet been asked or the question has been asked, and the answer matches the attribute of the suspect.

 gender(X) :- not(asked_gender) ; value_of(gender, X). 

Thus, if two suspects have the same eyes and age and different gender groups, if gender remains unoccupied, both of them will be plausible suspects.

However, the tricky part now is to automate the process of asking these questions. Basically, I'm looking forward to a solution in which Prolog was able to get the possible values ​​for the attributes from the suspects predicates, rather than listing the topic elsewhere. I am sure there must be a way to do this, since the prolog can use the program code as the data itself.

How could I do this?

+4
source share
2 answers

This works in SWI-Prolog:

 :- dynamic value/1. suspect('Person 1') :- eyes(blue) , age(old) , gender(male). suspect('Person 2') :- eyes(green) , age(young) , gender(male). suspect('Person 3') :- eyes(brown) , age(young) , gender(male). fetch(Criterion, Value) :- retractall(value(_)), assert(value([])), forall(clause(suspect(_), Body), check(Body, Criterion)), retract(value(Value)). check((F, T), Criterion) :- F =..[Criterion, V1], retract(value(V2)), ( member(V1, V2) -> V3 = V2; V3 = [V1 | V2]), assert(value(V3)). check(T, Criterion). check((_F, T), Criterion) :- check(T, Criterion). check((F), Criterion) :- F =..[Criterion, V1], retract(value(V2)), ( member(V1, V2) -> V3 = V2; V3 = [V1 | V2]), assert(value(V3)). check((_F), _Criterion). 

For instance: ? - selection (gender, value). Value = [man].

? - sample (eyes, value). Value = [brown, green, blue].

+3
source

Well, I would suggest such a construction:

 go :- findall(People,suspect(People),SuspectList), length(SuspectList,1), member(Perb,SuspectList), write('It is '),write(Perb),write('!!'),nl,!. go :- askQuestion, go. 

Where in askQuestion / 0 you ask questions with the read / 1 predicate and approve / 1 answers. Here you can try to make it “smart”, or you can just iterate over different questions.

0
source

Source: https://habr.com/ru/post/1412163/


All Articles