我有一个事实数据库,其中有类似这个片段的条目。
symptom(shingles,headache).
symptom(shingles,fever).
symptom(shingles,malaise).
symptom(shingles,headache).
symptom(shingles,itching).
symptom(shingles,hyperesthesia).
symptom(shingles,paresthesia).
test(shingles,blood).
test(shingles,pcr).
locale(shingles,all).
treatment(shingles,calamine).
treatment(shingles,aciclovir).
treatment(shingles,valaciclovir).
treatment(shingles,famciclovir).
treatment(shingles,corticosteroids).然后,我有一个谓词,它从用户那里获得一系列症状。
getSymptoms(Symptoms) :-
write('Please enter symptoms now, enter "Done" when finished: ' ),
read_string(user, "\n", "\r", _, Response),
(
Response == "Done"
->
Symptoms = []
;
getSymptoms(Symptoms0),
Symptoms = [Response|Symptoms0]
).我的问题是如何将用户症状列表与症状事实第二个原子进行比较,然后将疾病添加到另一个列表中?例如,用户进入发烧状态。由于发烧是带状疱疹的症状,它会把带状疱疹列入名单。
发布于 2019-02-15 21:23:15
这将工作,但允许重复的症状被输入。我现在发布它,以便您可以看到第一部分的转换,并将张贴部分,没有重复,当我得到工作。
getSymptoms(Symptoms) :-
write('Please enter symptoms now, enter "Done" when finished: ' ),
read_string(user, "\n", "\r", _, Response),
(
Response == "Done"
->
Symptoms = []
;
atom_string(Symptom,Response),
valid_symptom(Symptom,Symptoms)
).
valid_symptom(Symptom,Symptoms) :-
(
symptom(_,Symptom)
->
% Symptom was valid
% so get next symptom and
% add to list on backtracking
getSymptoms(Symptoms0),
Symptoms = [Symptom|Symptoms0]
;
% Symptom was invalid
% so warn user of invalid symptom and what they input
% and get next symptom.
% Do not add invalid Symptom to list on backtracking.
format('Invalid symptom: `~w''~n',[Symptom]),
getSymptoms(Symptoms0),
Symptoms = Symptoms0
).由于输入的值是字符串,而症状是symptom/2事实中的原子,因此需要将输入转换为原子进行比较。这是使用字符串/2完成的
atom_string(Symptom,Response) 若要向用户提供症状无效时的反馈,请使用格式/2。它比写/1更好,因为它使您对输出有更多的控制。
format('Invalid symptom: `~w''~n',[Symptom])如果输入无效值作为症状,则不应将其添加到列表中。这是典型的if/然后类型的场景,在Prolog中是用->/2完成的。以下是标准模板
(
<conditional>
->
<true branch>
;
<false branch>
)条件是
symptom(_,Symptom)还请注意,它读取symptom/2事实,忽略复合结构的第一部分,即_,并将输入症状与事实中的症状匹配。这是通过比较完成的,但是它是通过统一完成的,而不是通过=/2这样的比较谓词完成的。
真正的分支和以前一样。
getSymptoms(Symptoms0),
Symptoms = [Symptom|Symptoms0]然而,假分支是
format('Invalid symptom: `~w''~n',[Symptom]),
getSymptoms(Symptoms0),
Symptoms = Symptoms0请注意,无效的Symptom没有用[Symptom|Symptoms0]添加到列表中,而且两个分支(真和假)都应该更新相同的变量Symptoms,在假分支中,Symptoms是用Symptoms = Symptoms0完成的,而Symptoms = Symptoms0不是赋值,而是=/2 (统一)。
valid_symptom/2的代码可能包含了getSymptoms/1,但我提取了它,这样您就可以看到它是如何完成的,以防将来需要这样做。
示例运行:
?- getSymptoms(Symptoms).
Please enter symptoms now, enter "Done" when finished: wrong
Invalid symptom: `wrong'
Please enter symptoms now, enter "Done" when finished: headache
Please enter symptoms now, enter "Done" when finished: malaise
Please enter symptoms now, enter "Done" when finished: headache
Please enter symptoms now, enter "Done" when finished: Done
Symptoms = [headache, malaise, headache].下面是在构建列表时删除重复项的下一个变体。
getSymptoms(Result) :-
getSymptoms_helper([],Result).
getSymptoms_helper(Symptoms,Result) :-
write('Please enter symptoms now, enter "Done" when finished: ' ),
read_string(user, "\n", "\r", _, Response),
(
Response == "Done"
->
Result = Symptoms
;
atom_string(Symptom,Response),
valid_symptom(Symptom,Symptoms,Result)
).
valid_symptom(Symptom,Symptoms,Result) :-
(
memberchk(Symptom,Symptoms)
->
% Symptom was a duplicate
% Do not add duplicate Symptom to list.
getSymptoms_helper(Symptoms,Result)
;
(
symptom(_,Symptom)
->
% Symptom was valid
% so get next symptom and
% add to list.
getSymptoms_helper([Symptom|Symptoms],Result)
;
% Symptom was invalid
% so warn user of invalid symptom and what they input
% and get next symptom.
% Do not add invalid Symptom to list.
format('Invalid symptom: `~w''~n',[Symptom]),
getSymptoms_helper(Symptoms,Result)
)
).这里的主要变化是,累加器Symptoms通过谓词进行线程化,以便可以构建有效症状列表并用于测试下一个输入值。由于累加器需要在开始时初始化,所以前面的谓词重命名为getSymptoms_helper,以便可以用
getSymptoms_helper([],Result)注意传递给[]的
getSymptoms_helper(Symptoms,Result)因此,将Symptoms的初始值设置为[]。
当输入Done时,列表将与Result统一,并返回回链。通常情况下,变量将被命名为Symptoms0和Symptoms,但是我保留了它们,因此它们更易于跟踪。其他明智的方法是变量Symptom、Symptoms和Symptoms0,但是一旦您习惯了它们,就会更容易理解它们。
对重复项的检查是使用成员k/2完成的,这比使用成员/2进行检查要好。这再次为混合添加了另一个条件。
示例运行:
?- getSymptoms(Symptoms).
Please enter symptoms now, enter "Done" when finished: headache
Please enter symptoms now, enter "Done" when finished: malaise
Please enter symptoms now, enter "Done" when finished: headache
Please enter symptoms now, enter "Done" when finished: Done
Symptoms = [malaise, headache].https://stackoverflow.com/questions/54716395
复制相似问题