gpt4 book ai didi

Prolog if else 语法

转载 作者:行者123 更新时间:2023-12-04 23:19:33 25 4
gpt4 key购买 nike

我似乎无法让我的 if else 语句起作用。

  • 约翰、弗雷德和哈利是男性,玛丽、朱莉、苏珊和安妮是女性。
  • 约翰有一头金发,而弗雷德和哈利有一头黑发。
  • 朱莉和苏珊是金发,玛丽和安妮是黑发。
  • Rich 是每个拥有黄金的人——在我们的例子中是 Fred 和 Julie。
  • 男性只喜欢女性,反之亦然。而且,约翰和哈利喜欢有钱人,约翰喜欢金发,弗雷德喜欢黑发。
  • 玛丽和朱莉都喜欢黑头发的人,朱莉同时喜欢有钱人。

  • 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)).

    我想
    (Statement)->(如果为真则运行此语句);(如果为假则运行此语句)。
    在 Prolog 中是正确的方法。为什么不管我写什么
    likes(MaleName,FemaleName) 
    likes(FemaleName,MaleName)

    它返回true?

    最佳答案

    基于 CapelliC 的回答,因为显然他的回答不够明确。至于 if-else 语法和用法,请参阅答案末尾。

    首先,您在问题陈述中拥有的是您想要以 Prolog 程序形式表示的信息。在 Prolog 中,您有谓词,可以描述它们的参数之间的关系,或者陈述关于它们的参数的已知真理。例如,这是一个事实表;它说我们知道有七个人存在:

    person(john).person(fred).person(harry).person(mary).person(julie).person(susan).person(anne).

    Alright. We now want to state that some of them are male, and some are female.

    % John, Fred and Harry are men, Mary, Julie, Susan and Anne are women.male(john).male(fred).male(harry).female(mary).female(julie).female(susan).female(anne).

    These are two more tables of facts. Now you want to add to your database the information about their hair color:

    % John has blonde hair while Fred and Harry have dark hair.% Julie and Susan are blonde, Mary and Anne are 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 is a table with two columns if you will: the first is the person, the second one is a description of the hair color. The word "brunette" is usually used to describe a dark-haired woman, so we could add a rule that states that:

    % A brunette is a female with dark hairbrunette(X) :-    female(X),    person_hair(X, dark).

    Some of the people we have own gold, and owning gold in our program makes a 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 like women and women like men:

    person_likes(M, F) :-    male(M),    female(F).person_likes(F, M) :-    female(F),    male(M).

    As you can calculate, this gives us 3 x 4 + 4 x 3 = 24 possible solutions for person_likes(A, B) without any 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 is a very general rule: it describes a relationship between free variables, which makes it somewhat different from our person_owns/2 relationship, for example. Is it a really useful? Why not:

    is_heterosexual(H) :-    person(H).

    But this only states that every person in our program is heterosexual; it doesn't let us derive the rule that a heterosexual is someone who likes the opposite sex. Maybe it is even better to re-name it, to better express its meaning (and I will use an if-then-else construct, to show how it is normally done):

    opposite_sex(X, Y) :-    (   male(X)    ->  female(Y)    ;   female(X)    ->  male(Y)    ).

    For our purposes, this could have just as well written as above:

    opposite_sex(M, F) :-    male(M), female(F).opposite_sex(F, M) :-    male(M), female(F).

    With this, we can write a rule person_likes/2 with a general pre-condition stating that the other has to be of the opposite sex:

    person_likes(X, Y) :-    opposite_sex(X, Y),    fits_personal_taste(X, Y).

    We can now make rules for the personal tastes of each person. For Julie:

    fits_personal_taste(julie, X) :-    is_rich(X),    person_hair(X, dark).

    This creates a small problem, however. You need to make sure that for each person the program knows about there is a rule in this form. We don't know of any preferences for Anne, so we would have to have a rule:

    % Anyone (male) would fit Anne's tastesfits_personal_taste(anne, _).

    It would be nicer if we could instead have a table with an entry for each person that does have preferences, for example:

    person_preferences(julie, [is_rich, person_hair(dark)]).person_preferences(harry, [is_rich]).% and so on

    This would allow us to write fits_personal_taste/2 something like this:

    fits_personal_taste(X, Y) :-    (   person_preferences(X, Ps)    ->  maplist(fits_preference(Y), Ps)    ;   true    ).

    This is the intended use of an if-else construct in Prolog: an exclusive OR.

    If a person has preferences, check if the candidate fits all of them; otherwise succeed.

    How would fits_preference/2 look like though? It would take a person as the first argument, a term with the preference in the second, and would have to somehow check if that preference is met for that person. One somewhat hacky solution would be to use the so called Univ operator =.. to take the a term of the form person_hair(Color), make a term of the form person_hair(Person, Color), and call it:

    fits_preference(Person, Preference) :-
    Preference =.. [F|Args],
    Preference1 =.. [F,Person|Args],
    call(Preference1).

    最好是 person_preferences直接将一个人映射到可调用的术语:
    person_preferences(julie, P, [is_rich(P), person_hair(P, dark)]).person_preferences(harry, P, [is_rich(P)]).% and so 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 is called in the condition part of the statement, each preference in the list of preferences is bound to a concrete person; we then call each to check if it can be proven to be true for the facts in our program.

    Finally, a helper predicate possible_pair/2 that states that both people need to like each other:

    possible_pair(X, Y) :-
    person_likes(X, Y),
    person_likes(Y, X),
    X @< Y.

    最后一行将通过假设两个人应该严格按照顺序来确保我们不会两次得到同一对。

    有了这个,我得到:
    ?- bagof(A-B, possible_pair(A, B), R).
    R = [fred-mary, anne-fred].

    或者,对于单向“喜欢”列表,
    ?- 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, ... - ...|...].

    关于Prolog if else 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31529755/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com