1
votes

This is my first experience with Prolog. I am at the beginning stages of writing a program that will take input from the user (symptoms) and use that information to diagnose a disease. My initial thought was to create lists with the disease name at the head of the list and the symptoms in the tail. Then prompt the user for their symptoms and create a list with the user input. Then compare the list to see if the tails match. If the tails match then the head of the list I created would be the diagnosis. To start I scaled the program down to just three diseases which only have a few symptoms. Before I start comparing I need to build the tail of list with values read from the user but I can't seem to get the syntax correct.

This is what I have so far:

disease([flu,fever,chills,nausea]).
disease([cold,cough,runny-nose,sore-throat]).
disease([hungover,head-ache,nausea,fatigue]).

getSymptoms :-
    write('enter symptoms'),nl,
    read(Symptom),
    New_Symptom = [Symptom],
    append ([],[New_symptom],[[]|New_symptom]),
    write('are their more symptoms? y or n '),
    read('Answer'),
    Answer =:= y
    -> getSymptoms
    ; write([[]|New_symptom]).

The error occurs on the append line. Syntax Error: Operator Expected. Any help with this error or the design of the program in general would be greatly appreciated.

2
I tried changing the " | " to a " , " on the line with the append predicate but I still get Syntax Error: Operator expected. - bryan
You can't have a space between append and (. That should clear up the syntax error on that line. - lurker
Okay, I didn't know prolog doesn't like white space, good to know, however now when I run the program and enter input this is what I get: ?- getSymptoms. enter symptoms |: fever. are their more symptoms? y or n |: y. [[]|_G4695] true. 15 ?- I can't seem to figure out how to create a list using and undetermined number of user provided elements, going back to research prolog list, and recursion loops. uugghh ... - bryan
Your construct, append([], [New_symptom], [[] | New_symptom]) doesn't seem logical. Note that if A is a list, then [A] is a different list, which consists of one element, namely, the list A. That is, it's a list of lists which contains one element. You have New_symptom = [Symptom], then in your append you have [New_symptom] which is equivalent to [[Symptom]] which is not the same as [Symptom], etc. So, yes, you should review Prolog lists. See, 99 Prolog Problems as exercise examples. - lurker

2 Answers

2
votes

This is one way to read a list of symptoms in:

getSymptoms([Symptom|List]):-
    writeln('Enter Symptom:'),
    read(Symptom),
    dif(Symptom,stop),
    getSymptoms(List).

getSymptoms([]).

You type stop. when you want to finish the list.

You would then need to decide what logic you want to match the way you have represented a disease.

A complete example:

:-dynamic symptom/1.

diagnose(Disease):-
    retractall(symptom(_)),
    getSymptoms(List),
    forall(member(X,List),assertz(symptom(X))),
    disease(Disease).



getSymptoms([Symptom|List]):-
    writeln('Enter Symptom:'),
    read(Symptom),
    dif(Symptom,stop),
    getSymptoms(List).

getSymptoms([]).



disease(flue):-
    symptom(fever),
    symptom(chills),
    symptom(nausea).

disease(cold):-
   symptom(cough),
   symptom(runny_nose),
   symptom(sore_throat).

disease(hungover):-
   symptom(head_ache),
   symptom(nausea),
   symptom(fatigue).
0
votes

create(L1):-read(Elem),create(Elem,L1).

create(-1,[]):-!. create(Elem,[Elem|T]):-read(Nextel),create(Nextel,T).

go:- write('Creating a list'),nl, write('Enter -1 to stop'),nl, create(L), write('List is:'), write(L).