i can't seem if else statement work.
- john, fred , harry men, mary, julie, susan , anne women.
- john has blonde hair while fred , harry have dark hair.
- julie , susan blonde, mary , anne brunette.
- rich each person owns gold - fred , julie in our example.
- male female , vice versa. moreover, john , harry rich persons,john likes blonde , fred likes brunette.
- both mary , julie dark hair persons, julie likes rich persons @ same time.
male(john). male(fred). male(harry). female(mary). female(julie). female(susan). female(anne). hasblonde(x):-(male(x),x = john);(female(x),x = susan);(female(x),x = julie). hasdarkhair(x):-(male(x),x = harry);(male(x),x = fred). hasbrunette(x):-(female(x),x = mary);(female(x),x = anne). isrich(x):-(female(julie),x=julie);(male(fred),x=fred). likes(male(x),female(y));likes(female(x),male(y)):-likes(x,y). likes(x,y):- ((x==julie)-> ((hasdarkhair(y))-> (female(x), male(y)); male(x)); female(x),male(y)); ((x==julie)-> ((isrich(y))-> (female(x), male(y)); male(x)); female(x),male(y)); ((x=mary)-> ((hasdarkhair(y))-> (female(x), male(y)); male(x)); female(x),male(y)); ((x=john)-> ((isrich(y))-> (female(x), male(y)); female(x)); male(x),female(y)); ((x=harry)-> ((isrich(y))-> (female(x), male(y)); female(x)); male(x),female(y)); ((x=fred)-> ((hasbrunette(y))-> (female(x), male(y)); female(x)); male(x),female(y)). i thought (statement)->(if true run statement);(if false run statement). right approach in prolog. why no matter write
likes(malename,femalename) likes(femalename,malename) it returns true?
building upon answer capellic, because apparently answer not explicit enough. if-else syntax , use, see towards end of answer.
first off, have in problem statement information want represent in form of prolog program. in prolog, have predicates, can describe relationships between arguments, or state known truths arguments. here example table of facts; states there 7 people know exist:
person(john). person(fred). person(harry). person(mary). person(julie). person(susan). person(anne).
alright. want state of them male, , female.
% john, fred , harry men, mary, julie, susan , anne women. male(john). male(fred). male(harry). female(mary). female(julie). female(susan). female(anne).
these 2 more tables of facts. want add database information hair color:
% john has blonde hair while fred , harry have dark hair. % julie , susan blonde, mary , anne brunette. person_hair(john, blond). person_hair(fred, dark). person_hair(harry, dark). person_hair(julie, blond). person_hair(susan, blond). person_hair(mary, dark). person_hair(anne, dark).
this table 2 columns if will: first person, second 1 description of hair color. word "brunette" used describe dark-haired woman, add rule states that:
% a brunette female dark hair brunette(x) :- female(x), person_hair(x, dark).
some of people have own gold, , owning gold in our program makes person rich:
person_owns(fred, gold). person_owns(julie, gold). is_rich(x) :- %person(x), person_owns(x, gold).
in our strictly heterosexual program, men women , women men:
person_likes(m, f) :- male(m), female(f). person_likes(f, m) :- female(f), male(m).
as can calculate, gives 3 x 4 + 4 x 3 = 24 possible solutions person_likes(a, b) without further constraints:
?- bagof(a-b, person_likes(a, b), r), length(r, len). r = [john-mary, john-julie, john-susan, john-anne, fred-mary, fred-julie, fred-susan, fred-anne, ... - ...|...], len = 24.
this general rule: describes relationship between free variables, makes different our person_owns/2 relationship, example. useful? why not:
is_heterosexual(h) :- person(h).
but states every person in our program heterosexual; doesn't let derive rule heterosexual likes opposite sex. maybe better re-name it, better express meaning (and use if-then-else construct, show how done):
opposite_sex(x, y) :- ( male(x) -> female(y) ; female(x) -> male(y) ).
for our purposes, have written above:
opposite_sex(m, f) :- male(m), female(f). opposite_sex(f, m) :- male(m), female(f).
with this, can write rule person_likes/2 general pre-condition stating other has of opposite sex:
person_likes(x, y) :- opposite_sex(x, y), fits_personal_taste(x, y).
we can make rules personal tastes of each person. julie:
fits_personal_taste(julie, x) :- is_rich(x), person_hair(x, dark).
this creates small problem, however. need make sure for each person program knows about there rule in form. don't know of preferences anne, have have rule:
% anyone (male) fit anne's tastes fits_personal_taste(anne, _).
it nicer if instead have table entry each person does have preferences, example:
person_preferences(julie, [is_rich, person_hair(dark)]). person_preferences(harry, [is_rich]). % , on
this allow write fits_personal_taste/2 this:
fits_personal_taste(x, y) :- ( person_preferences(x, ps) -> maplist(fits_preference(y), ps) ; true ).
this intended use of if-else construct in prolog: exclusive or.
if person has preferences, check if candidate fits of them; otherwise succeed.
how fits_preference/2 though? take person first argument, term preference in second, , have somehow check if preference met person. 1 hacky solution use called univ operator =.. take term of form person_hair(color), make term of form person_hair(person, color), , call it:
fits_preference(person, preference) :- preference =.. [f|args], preference1 =.. [f,person|args], call(preference1). it maybe better person_preferences directly maps person callable terms:
person_preferences(julie, p, [is_rich(p), person_hair(p, dark)]). person_preferences(harry, p, [is_rich(p)]). % , on
with this, fits_personal_taste/2 becomes:
fits_personal_taste(x, y) :- ( person_preferences(x, y, ps) -> maplist(call, ps) ; true ).
when person_preferences/3 called in condition part of statement, each preference in list of preferences bound concrete person; call each check if can proven true facts in our program.
finally, helper predicate possible_pair/2 states both people need each other:
possible_pair(x, y) :- person_likes(x, y), person_likes(y, x), x @< y. the last line make sure don't same pair twice postulating 2 persons should in strict order.
with this, get:
?- bagof(a-b, possible_pair(a, b), r). r = [fred-mary, anne-fred]. or, list of one-directional "likes",
?- bagof(a-b, person_likes(a, b), r), write(r). [john-julie,fred-mary,fred-anne,harry-julie,susan-john,anne-john,mary-fred,julie-fred,susan-fred,anne-fred,mary-harry,susan-harry,anne-harry] r = [john-julie, fred-mary, fred-anne, harry-julie, susan-john, anne-john, mary-fred, julie-fred, ... - ...|...].
Comments
Post a Comment