我能';I don’我不理解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

我正在为我的研究做Prolog编程,我遇到了一些问题。。 首先,我所有的代码都在下面

%% 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。。。我为我的目的制定了适当的代码。谢谢!!!:)你给了我很多信息。