Prolog:生成包含满足谓词的成员的子列表

时间:2016-04-06 11:25:05

标签: list prolog

我要做的是从列表中生成子列表,其中每个成员都满足谓词。所以在一个名为heightMatchList(Person1,HeightMatchList)的仿函数中,我想通过调用genderMatchList并将GenderMatchList的成员添加到HeightMatchList来查看GenderMatchList的每个成员,如果这些成员满足谓词heightMatch(Person1,Person2),其中Person2是正在检查GenderMatchList的成员。

该程序应根据一些信息与人匹配。我想使用这个子列表方法而不是使用bagof或findall的原因是我只想从已满足性别要求的人群中搜索满足身高要求的候选人。我已经尝试在线搜索生成子列表,其中成员满足谓词,但他们通常会返回bagof或findall。这不合适,因为搜索空间不仅限于列表。

非常感谢任何帮助。

代码:

different(Person1,Person1):-
    !,
    fail.
different(_,_).

gender(Person,Gender):-
    person(Person,Gender,_,_,_,_,_,_).

genderPref(Person,GenderPref):-
    person(Person,_,GenderPref,_,_,_,_,_).

height(Person,Height):-
    person(Person,_,_,Height,_,_,_,_).

heightPref(Person,Height):-
    person(Person,_,_,_,Height,_,_,_).

weight(Person,Weight):-
    person(Person,_,_,_,_,Weight,_,_).

weightPref(Person,WeightPref):-
    person(Person,_,_,_,_,_,WeightPref,_).

petPref(Person,PetPref):-
    person(Person,_,_,_,_,_,_,PetPref).

genderMatch(Person1,Person2):-
    gender(Person1,Gender1),
    genderPref(Person2,Gender1),
    gender(Person2,Gender2),
    genderPref(Person1,Gender2),
    different(Person1,Person2).

heightMatch(Person1,Person2):-
    height(Person1,Height1),
    heightPref(Person2,Height1),
    height(Person2,Height2),
    heightPref(Person1,Height2),
    different(Person1,Person2).

weightMatch(Person1,Person2):-
    weight(Person1,Weight1),
    weightPref(Person2,Weight1),
    weight(Person2,Weight2),
    weightPref(Person1,Weight2),
    different(Person1,Person2).

petMatch(Person1,Person2):-
    petPref(Person1,Pet),
    petPref(Person2,Pet),
    different(Person1,Person2).

match(Person1,Person2):-
    genderMatch(Person1,Person2),
    heightMatch(Person1,Person2),
    weightMatch(Person1,Person2),
    petMatch(Person1,Person2).

genderMatchList(Person,GenderMatchList):-
    findall(X,genderMatch(Person,X),GenderMatchList).

编辑:

如果需要,可以使用一些测试数据:

person(alice,female,male,small,medium,average,average,dog).
person(barry,male,female,medium,small,average,average,dog).
person(clara,female,female,tall,tall,average,average,cat).
person(danny,male,female,small,medium,average,average,cat).
person(elise,female,male,medium,small,average,average,dog).
person(fred,male,female,tall,small,average,average,dog).
person(grace,female,female,small,medium,average,average,dog).
person(harry,male,female,medium,tall,average,average,cat).
person(isabella,female,male,tall,tall,average,average,cat).
person(jack,male,female,small,medium,average,average,dog).
person(katie,female,female,medium,tall,average,average,dog).
person(larry,male,female,tall,tall,average,average,cat).
person(mel,female,male,small,medium,average,average,cat).
person(nathan,male,female,medium,small,average,average,dog).
person(olivia,female,female,tall,small,average,average,dog).
person(peter,male,female,small,medium,average,average,cat).
person(quinn,female,female,medium,tall,average,average,cat).
person(robert,male,female,tall,tall,average,average,dog).
person(sophie,female,male,small,medium,average,average,dog).
person(tom,male,female,medium,small,average,average,cat).
person(ursula,female,female,tall,small,average,average,cat).
person(vincent,male,female,small,medium,average,average,dog).
person(wendy,female,male,medium,tall,average,average,dog).
person(xavier,male,female,tall,tall,average,average,cat).
person(yvonne,female,female,small,medium,average,average,cat).
person(zed,male,female,medium,small,average,average,cat).

2 个答案:

答案 0 :(得分:2)

您可以编写一个谓词来查找某人的性别和身高匹配:

person_hgmatch(Person1,Person2) :-    % Person2 is a
    genderMatch(Person1,Person2),     % gender match for Person1 AND
    heightMatch(Person1,Person2).     % height match for Person1

现在你可以获得比赛,例如巴里一个接一个地说:

  ?- person_hgmatch(barry,X).
X = alice ? ;
X = mel ? ;
X = sophie ? ;
no

基于此,您可以编写一个谓词,为您提供列表中的所有匹配项:

person_allhgmatches(Person,M) :-
    findall(X,person_hgmatch(Person,X),M).

   ?- person_allhgmatches(barry,X).
X = [alice,mel,sophie]

我认为(a)描述匹配的所有要求的谓词会更容易,而且最后只聚合而不是从头开始为每个匹配标准操作列表。

关于你对不同/ 2的定义:你是否知道谓词dif / 2?它做了你似乎打算用不同的/ 2做的事情。例如,您的谓词heightMatch / 2可能看起来像这样:dif / 2:

heightMatch(Person1,Person2):-
    dif(Person1,Person2),
    height(Person1,Height1),
    heightPref(Person2,Height1),
    height(Person2,Height2),
    heightPref(Person1,Height2).

无需摆弄剪切(!): - )

答案 1 :(得分:2)

  

希望从已满足性别要求的人群中搜索满足身高要求的候选人

Prolog有一个关系数据模型,所以只需加入所有要求:

match_requirements(Person, Requirements, Candidate) :-
    person(Candidate,_,_,_,_,_,_,_),
    forall(member(R, Requirements), call(R, Person, Candidate)).

示例:

?- match_requirements(barry,[genderMatch,heightMatch],P).
P = alice ;
P = mel ;
P = sophie ;
false.