我无法理解我在 Prolog 编程中的代码结果 [英] I can't understand the result of my code in Prolog Programming

查看:36
本文介绍了我无法理解我在 Prolog 编程中的代码结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am doing Prolog Programming for my research and I got some problems.. First, all of my codes are below.

%% 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 条输入行制作一个条形图.但是当我执行这段代码时,我得到的结果如下...

As you can see, I want to make a bar_graph from 10 input lines by extracting symptoms.. But when I executed this code, I got the result as below...

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 

我只输入了一种症状 (runny_nose).我想得到cold"的分数是 0,severe_cold"的分数是 50 和 BarGraph 结果......但是发生了什么?我找不到..

I only typed one symptom (runny_nose). I want to get Score for "cold" is 0, Score for "severe_cold" is 50 and BarGraph result... But What Happened? I can't find..

*****已编辑******我发现问题与局部变量(Line1,..,Line10)有关,但我该如何处理?如果我可以制作所有的变量;Line1, ... , Line10 作为全局变量 那么,我认为问题可以解决...

*****Edited****** I found that the problem is related to local variables (Line1, .. ,Line10) But how can I deal with? If I can make all the variables; Line1, ... , Line10 as global variables then, I think the problem can be solved...

****添加*****

****Addition*****

我将开始"谓词更改如下...我没有使用诊断"和假设"谓词/但问题可能是...get_symptoms"谓词.除了不使用get_symptoms"和symptoms"谓词之外,还有什么我可以选择的选择吗?那么代码就会变得很粗糙...

I changed my 'start' predicate as follows...I didn't use 'diagnosis' and 'hypothesis' predicates/ But the problems is maybe.. 'get_symptoms' predicate. Is there any choice I can choose except that I don't use 'get_symptoms' and 'symptoms' predicates...? Then the code will become very coarse...

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 根本不像其他通用语言那样工作.

When programming in Prolog, you need to do some research into the language to understand how it works. Many Prolog beginners make the mistake of learning a couple of snippets of Prolog logic and then apply what they know of other languages to attempt to create a valid Prolog programming. However, Prolog doesn't work like other common languages at all.

关于变量,没有全局变量.变量对于谓词子句总是本地的".谓词子句是描述谓词的一个或多个子句之一.例如:

Regarding variables, there are no globals. Variables are always "local" to a predicate clause. A predicate clause is one of one or more clauses that describe a predicate. For example:

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的三个子句.在一个子句中实例化的 XY 的值对其他子句不可见.

These are three clauses describing the predicate foo/2. The value of X or Y instantiated in one clause isn't visible to the other clauses.

如果你想在一个谓词中实例化一个变量并在另一个谓词中使用它,你必须将它作为参数传递:

If you want to instantiate a variable in one predicate and use it in another, you have to pass it as a parameter:

foo([1,2,3,4], L),
bar(L, X).

这里,foo 可能会使用一些逻辑并基于 [1,2,3,4] 的实例化值实例化 L第一个论点.然后将 L(现在已实例化)作为第一个参数传递给谓词 bar.

Here, foo might instantiate L using some logic and based upon the instantiated value of [1,2,3,4] for the first argument. Then L (now instantiated) is passed as the first argument to the predicate bar.

如果你需要一个值作为数据持久化,你可以将它作为一个事实来断言,如下所示:

If you need a value to be persistent as data, you could assert it as a fact as follows:

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 信息数据库.

This would work, but is not a desirable approach in Prolog to "fake" global variables. Asserting items into persistent data is designed for the purpose of maintaining a Prolog database of information.

所以你可以看到你的逻辑涉及到 Line1, Line2, ... 将不起作用.一个线索是您一定收到了许多关于这些变量是单例"的警告.您需要多学习一点 Prolog,然后使用这些知识重新构建您的逻辑.

So you can see that the logic you have involving Line1, Line2, ... will not work. One clue would be that you must have received many warnings about these variables being "singleton". You need to study Prolog a bit more, then recast your logic using that knowledge.

这篇关于我无法理解我在 Prolog 编程中的代码结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆