Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何将列表与数据库序言进行比较_List_Prolog_Compare - Fatal编程技术网

List 如何将列表与数据库序言进行比较

List 如何将列表与数据库序言进行比较,list,prolog,compare,List,Prolog,Compare,我有一个事实数据库,里面有这样的条目 symptom(shingles,headache). symptom(shingles,fever). symptom(shingles,malaise). symptom(shingles,headache). symptom(shingles,itching). symptom(shingles,hyperesthesia). symptom(shingles,paresthesia). test

我有一个事实数据库,里面有这样的条目

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]
    ).
我的问题是如何将用户症状列表与第二个atom的症状事实进行比较,然后将疾病添加到另一个列表中?
例如,用户输入发烧。由于带状疱疹的症状事实中有发热,它会将带状疱疹添加到列表中。

这会起作用,但允许输入重复的症状。我现在发布它,以便您可以看到转换的第一部分,并在我开始工作时发布没有副本的部分

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
    ).
由于输入的值是字符串,症状是
症状/2
事实中的原子,因此需要将输入转换为原子以进行比较。这是通过使用

如果症状无效,则向用户提供反馈。使用它比使用它更好,因为它可以让您更好地控制输出

format('Invalid symptom: `~w''~n',[Symptom])
如果为输入了无效值作为症状,则不应将其添加到列表中。这是一个典型的if/then类型的场景,在Prolog中使用。这是标准模板

(
    <conditional>
->
    <true branch>
;
    <false branch>
)
请注意,还有一个条件,它读取
症状/2
事实,忽略复合结构的第一部分,即
\u
,并将输入症状与事实中的症状相匹配。这是因为比较已经完成,但它是通过统一完成的,而不是使用比较谓词,例如

真正的分支与以前一样

getSymptoms(Symptoms0),
Symptoms = [Symptom|Symptoms0]
然而,错误的分支是

format('Invalid symptom: `~w''~n',[Symptom]),
getSymptoms(Symptoms0),
Symptoms = Symptoms0
请注意,无效的
症状
没有添加到带有
[Symptom | Symptoms0]
的列表中,而且两个分支(true和false)都应该更新相同的变量
症状
,在false分支中,这些变量是通过
症状=症状0
完成的,而不是赋值,而是(统一)

valid\u 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(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].

下面是在构建列表时删除重复项的下一个变体

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)
        )
    ).
这里的主要变化是累加器
症状
通过谓词进行线程化,以便可以构建有效症状列表并用于测试下一个输入值。由于累加器需要在开始时初始化,因此前面的谓词重命名为
getSymptoms\u helper
,以便可以使用

getSymptoms_helper([],Result)
请注意传递到的
[]

getSymptoms_helper(Symptoms,Result)
因此,将
症状的初始值设置为
[]

当输入
Done
时,列表与
Result
统一,并在反向链接时传回。通常情况下,变量将被命名为
symples0
symples
,但我以这种方式保存它们,以便更容易理解。另一方面,可能会有变量
症状
症状
症状0
,但一旦你习惯了它们,就更容易理解

检查重复项时使用的是比检查更好的方法。这再次为混合添加了另一个条件

运行示例:

?- 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(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].

相关问题:。@GuyCoder正在看这个。你能提供的任何例子都会有帮助,因为这是我第一次使用prolog,我需要学习它。哇,谢谢你花这么多时间在这上面。我有几个问题是,我已经走上了正轨,你是否有这个“有效的症状(症状,症状):-(症状(,症状)…)但我试图保持症状与哪种疾病相关。我尝试这样的检查症状(症状,症状):-(症状(疾病,症状)->getSymptoms(症状0),症状=[症状|症状0],Diseases=[Disease | Diseas0]…“这是一种方法吗?@user10876930我不会这样做,因为您正在创建两个单独的列表,例如
症状=[Symptom | Symptoms0]
疾病=[Disease | Diseas0].
要求两者始终同步。如果从其中一个项目中删除某个项目,则会出现问题。最好使用元组或更好的复合术语创建列表,例如,
[症状(带状疱疹、头痛)、症状(带状疱疹、瘙痒)]
。我知道这看起来像是在复制症状事实中的值,但效果会更好。你应该作为一个单独的问题来提问,并获得更多的分数。@user10876930如果你问了这个问题,请思考你如何需要下一部分的数据,并在问题中解释。如果你以你写的方式提问,我会在这里,当你有几种疾病的几种症状时,数据可以在提取时以不同的方式排列,避免重新排列的麻烦,例如
[XYZ,[ABC,DEF],UVW,[GHI,JKL,MNO]]
其中第一部分是疾病,第二部分是症状列表。好的,我明白你关于必须保持两个列表同步的意思。我现在将查看元组/复合列表。再次感谢你花时间回答问题并提供解释!