我能';I don’我不理解Prolog编程中代码的结果
我正在为我的研究做Prolog编程,我遇到了一些问题。。 首先,我所有的代码都在下面我能';I don’我不理解Prolog编程中代码的结果,prolog,Prolog,我正在为我的研究做Prolog编程,我遇到了一些问题。。 首先,我所有的代码都在下面 %% Lines are without period(.) diagnosis :- readln(Line1), readln(Line2), readln(Line3), readln(Line4), readln(Line5), readln(Line6), readln(Line7), readln(Line8), readln
%% Lines are without period(.)
diagnosis :-
readln(Line1),
readln(Line2),
readln(Line3),
readln(Line4),
readln(Line5),
readln(Line6),
readln(Line7),
readln(Line8),
readln(Line9),
readln(Line10),
write(Line1),nl,
write(Line2),nl,
write(Line3),nl,
write(Line4),nl,
write(Line5),nl,
write(Line6),nl,
write(Line7),nl,
write(Line8),nl,
write(Line9),nl,
write(Line10),nl.
%% (get_symptom(Line1,[man]) -> write('man!!!!!!!!!')),
%% (get_symptom(Line2,[woman]) -> write('woman!!!!!!!!!')).
%% if A then B else C, (A->B; C)
%% grammar
s --> np, vp.
np --> det, n.
vp --> v, np.
det --> [a].
n --> [man].
v --> [has].
n --> [woman].
n --> [fever].
n --> [runny_nose].
get_symptom(Line,N) :- s(Line,[]), member(N,Line).
member(X, [X|T]).
member(X,[H|T]) :-
member(X,T).
%% FindSymptom(Line, [Symptom]) : - s(Line,[]), np(_, _, object,[a,
%% Symptom]), n(singular, [Symptom], []).
start :-
write('What is the patient''s name? '),
readln(Patient), %% Here, this can be used for input of all symtoms
diagnosis,
hypothesis(Patient,cold,S1),
append([cold/S1/red],[],N1), write(S1),
write('until...'),
hypothesis(Patient,severe_cold,S2), write(S2),
append([severe_cold/S2/red],N1,BarList),
write('until...'),
%% write(Patient,"probably has ",Disease,"."),nl.
hypothesis(Patient,Disease,100),
write(Patient),
write(' probably has '),
write(Disease),
write('.'),
test_barchart(BarList).
start :-
write('Sorry, I don''t seem to be able to'),nl,
write('diagnose the disease.'),nl.
symptom(Patient,fever) :-
get_symptom(Line1, [fever]);
get_symptom(Line2, [fever]);
get_symptom(Line3, [fever]);
get_symptom(Line4, [fever]);
get_symptom(Line5, [fever]);
get_symptom(Line6, [fever]);
get_symptom(Line7, [fever]);
get_symptom(Line8, [fever]);
get_symptom(Line9, [fever]);
get_symptom(Line10, [fever]).
symptom(Patient,runny_nose) :-
get_symptom(Line1, [runny_nose]);
get_symptom(Line2, [runny_nose]);
get_symptom(Line3, [runny_nose]);
get_symptom(Line4, [runny_nose]);
get_symptom(Line5, [runny_nose]);
get_symptom(Line6, [runny_nose]);
get_symptom(Line7, [runny_nose]);
get_symptom(Line8, [runny_nose]);
get_symptom(Line9, [runny_nose]);
get_symptom(Line10, [runny_nose]).
hypothesis(Patient,cold,Score_Cold) :-
(symptom(Patient,fever), Score_Cold is 100),write('!!!');
Score_Cold is 0.
hypothesis(Patient,severe_cold,Score_Severe) :-
((symptom(Patient,fever), Score1 is 50);
Score1 is 0),
((symptom(Patient, runny_nose), Score2 is 50);
Score2 is 0),
Score_Severe is Score1 + Score2.
%% hypothesis(Disease) :-
%%(hypothesis1(Patient,cold,Score1),
%%Score1 =:= 100 -> Disease = cold);
%%(hypothesis2(Patient,severe_cold,Score2),
%%Score2 =:= 100 -> Disease = severe_cold).
%% make graph for the result
:- use_module(library(pce)).
:- use_module(library(plot/barchart)).
:- use_module(library(autowin)).
test_barchart(BarList):-
new(W, picture),
send(W, display, new(BC, bar_chart(vertical,0,100))),
forall(member(Name/Height/Color,
BarList),
( new(B, bar(Name, Height)),
send(B, colour(Color)),
send(BC, append, B)
)),
send(W, open).
%% [X/100/red, y/150/green, z/80/blue, v/50/yellow]
%% append List
append([], L, L).
append([H|T], L2, [H|L3]):-
append(T, L2, L3).
如你所见,我想通过提取症状,从10条输入线中绘制一个条形图。。
但是当我执行这段代码时,我得到的结果如下
1 ?- start.
What is the patient's name? GJ
|: a man has a runny_nose
|: a
|: a
|: a
|: a
|: a
|: a
|: a
|: a
|: a
[a,man,has,a,runny_nose]
[a]
[a]
[a]
[a]
[a]
[a]
[a]
[a]
[a]
!!!100until...100until...!!![GJ] probably has cold.
true
我只输入了一种症状(流鼻涕)。我想得到“感冒”的分数是0,“严重感冒”的分数是50,条形图结果。。。但是发生了什么?我找不到
*****编辑*******
我发现问题与局部变量(第1行,…,第10行)有关,但我如何处理?如果我能使所有的变量;第1行,第10行作为全局变量,我认为这个问题可以解决
****加成*****
我改变了我的“开始”谓词如下…我没有使用“诊断”和“假设”谓词/但问题可能是..”获取症状的谓词。除了我不使用'get_symptoms'和'symptoms'谓词之外,还有其他选择吗。。。?然后代码将变得非常粗糙
start :-
write('What is the patient''s name? '),
readln(Patient), %% Here, this can be used for input of all symtom
readln(Line1),
readln(Line2),
readln(Line3),
readln(Line4),
readln(Line5),
readln(Line6),
readln(Line7),
readln(Line8),
readln(Line9),
readln(Line10),
(symptom(Patient,fever,Line1,Line2,Line3,Line4,Line5,Line6,Line7,Line8,Line9,Line10) -> (Cold is 80, Severe_Cold is 50)),
(symptom(Patient,runny_nose,Line1,Line2,Line3,Line4,Line5,Line6,Line7,Line8,Line9,Line10) -> Severe_Cold is Severe_Cold + 50),
write(Severe_Cold), write(Cold),
append([cold/Cold/red],[],N1),
append([severe_cold/Severe_Cold/red],N1,BarList),
%% write(Patient,"probably has ",Disease,"."),nl.
write(Severe_Cold),
((Cold =:= 100 -> Disease = cold) ; (Severe_Cold =:= 100 -> Disease = severe_cold)),
write(Patient),
write(' probably has '),
write(Disease),
write('.'),
test_barchart(BarList).
当使用Prolog编程时,您需要对该语言进行一些研究,以了解它是如何工作的。许多Prolog初学者错误地学习了几个Prolog逻辑片段,然后应用他们对其他语言的了解来尝试创建一个有效的Prolog编程。然而,Prolog根本不像其他通用语言那样工作 关于变量,没有全局变量。变量总是谓词子句的“局部”。谓词子句是描述谓词的一个或多个子句之一。例如:
foo(X, Y) :- (some logic including X and Y).
foo(X, Y) :- (some other logic including X and Y).
foo(X, X) :- (some other logic including X).
这三个子句描述谓词foo/2
。在一个子句中实例化的X
或Y
的值对其他子句不可见
如果要在一个谓词中实例化变量并在另一个谓词中使用,则必须将其作为参数传递:
foo([1,2,3,4], L),
bar(L, X).
这里,foo
可以使用一些逻辑并基于第一个参数的[1,2,3,4]
的实例化值来实例化L
。然后将L
(现在已实例化)作为第一个参数传递给谓词bar
如果需要一个值作为数据持久化,则可以将其作为事实进行断言,如下所示:
foo :-
(some logic that determines X),
assertz(my_fact(X)),
(more logic).
bar :-
my_fact(X), % Will instantiate X with what was asserted
(some logic using X).
这是可行的,但在Prolog中不是一种理想的“伪造”全局变量的方法。将项断言为持久性数据是为了维护Prolog信息数据库而设计的
因此,您可以看到所涉及的逻辑包括
Line1
,Line2
。。。这是行不通的。一个线索是,您一定收到过很多关于这些变量是“单例”的警告。您需要进一步学习Prolog,然后使用这些知识重新构建您的逻辑。我更改了一些代码并编辑了上面的文章。您可以从添加**部分看到。。。另一个问题发生了。。很抱歉我真的是个编程新手。@GoodGJ我很高兴能帮上忙。很多Prolog初学者都会陷入同样的陷阱和问题,所以不用担心。如果你对Prolog是认真的,我建议你找一本好书或教程来热身,让它与众不同。追加([cold/cold/red],],N1),的目的是什么?重度感冒是重度感冒+50
总是会失败。一旦一个变量被实例化,你就不能在没有回溯的情况下重新实例化它,因此这将询问Severe\u Cold
的值本身是否为+50,这永远不会是真的。这需要您进一步学习一些Prolog基础知识。:)在这种情况下,使用一个新的变量名,例如,SC1是严重的+50
,然后在子句的其余部分使用SC1
。可能还有其他问题,但我马上就发现了这个问题。@mbrach append([cold/cold/red],],N1),。。。是用来制作条形图的。在这里,我以前要求做一个条形图。我使用了一个人给我的示例代码。append([cold/cold/red],[N1],N1)
只是在[cold/cold/red]
中不附加任何内容,并用结果实例化N1
。所以这和刚才说的一样,N1=[cold/cold/red]
@mbrach Now。。。我为我的目的制定了适当的代码。谢谢!!!:)你给了我很多信息。