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).
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
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..
*****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*****
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).
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:
These are three clauses describing the predicate
foo/2
. The value ofX
orY
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:
Here,
foo
might instantiateL
using some logic and based upon the instantiated value of[1,2,3,4]
for the first argument. ThenL
(now instantiated) is passed as the first argument to the predicatebar
.If you need a value to be persistent as data, you could assert it as a fact as follows:
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.
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.