如何在Prolog中应用全称量词?

发布于 2024-11-18 10:47:29 字数 529 浏览 1 评论 0原文

假设您有一个疾病诊断 Prolog 程序,该程序以疾病和症状之间的许多关系开始:

causes_of(symptom1, Disease) :-
    Disease = disease1;
    Disease = disease2.
causes_of(symptom2, Disease) :-
    Disease = disease2;
    Disease = disease3.
causes_of(symptom3, Disease) :-
    Disease = disease4.

has_symptom(person1, symptom1).
has_symptom(person1, symptom2).

我如何创建一个以“has_disease(Person,Disease)”为头的规则,如果该人具有该疾病的所有症状,该规则将返回 true?使用上面的示例,以下是示例输出:

has_disease(person1, Disease).
   Disease = disease2.

Suppose you have a disease diagnosis Prolog program that starts with many relations between diseases and symptons:

causes_of(symptom1, Disease) :-
    Disease = disease1;
    Disease = disease2.
causes_of(symptom2, Disease) :-
    Disease = disease2;
    Disease = disease3.
causes_of(symptom3, Disease) :-
    Disease = disease4.

has_symptom(person1, symptom1).
has_symptom(person1, symptom2).

How can I create a rule with the head 'has_disease(Person, Disease)' that will return true if the person has all the symptoms from that disease? Using the example above the following would a sample output:

has_disease(person1, Disease).
   Disease = disease2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ㄖ落Θ余辉 2024-11-25 10:47:29

好吧,可能有一种更简单的方法可以做到这一点,因为我的 Prolog 技能充其量只是次要的。

has_disease(Person, Disease) :- atom(Disease),
    findall(Symptom, has_symptom(Person, Symptom), PersonSymptoms),
    findall(DSymptom, causes_of(DSymptom, Disease), DiseaseSymptoms),
    subset(DiseaseSymptoms, PersonSymptoms).

has_diseases(Person, Diseases) :-
    findall(Disease, (causes_of(_, Disease), has_disease(Person, Disease)), DiseaseList),
    setof(Disease, member(Disease, DiseaseList), Diseases).

调用方式如下:

?- has_diseases(person1, D).
D = [disease1, disease2, disease3].

findall/3 谓词首先用于查找一个人具有的所有症状,然后再次查找一种疾病具有的所有症状,然后快速检查该疾病的症状是否是该人的症状的子集。

我编写 has_disease/2 谓词的方式阻止它给出疾病列表。因此,我创建了 has_diseases/2,它使用 has_disease/2 作为检查,对它能找到的任何疾病执行另一个 findall 操作。 setof/3 调用是最后使用以获得疾病列表上的独特结果并为了方便而订购。

注意。上的 atom/1 has_disease/2 原语只是为了确保不会为 Disease 传入变量,因为它在这种情况下不起作用,至少对我来说不起作用。

Well, there is probably a much simpler way to do this, as my Prolog skills are minor at best.

has_disease(Person, Disease) :- atom(Disease),
    findall(Symptom, has_symptom(Person, Symptom), PersonSymptoms),
    findall(DSymptom, causes_of(DSymptom, Disease), DiseaseSymptoms),
    subset(DiseaseSymptoms, PersonSymptoms).

has_diseases(Person, Diseases) :-
    findall(Disease, (causes_of(_, Disease), has_disease(Person, Disease)), DiseaseList),
    setof(Disease, member(Disease, DiseaseList), Diseases).

To be called as follows:

?- has_diseases(person1, D).
D = [disease1, disease2, disease3].

The findall/3 predicate is used first to find all symptoms a person has, then again to find all symptoms a disease has, then a quick check to see if the disease's symptoms are a subset of the person's.

The way I have written the has_disease/2 predicate prevents it from giving a list of diseases. So I created has_diseases/2, which performs another findall on any disease it can find, using has_disease/2 as the check. A setof/3 call is used last to get unique results on the disease list and order it for convenience.

NB. The atom/1 on the has_disease/2 primitive is just to ensure a variable is not passed in for Disease, as it does not work in that case, at least not for me.

紅太極 2024-11-25 10:47:29

您将需要一种查询所有症状的方法,例如使用 findall(S,cause_of(S,disease),SS),其中 SS 将是此症状的列表疾病。

You will need a way to query all symptoms, e.g. with findall(S,cause_of(S,disease),SS), where SS will be the list of symptoms for this disease.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文