Discussions related to Visual Prolog
Michel
Posts: 2
Joined: 8 Nov 2025 17:17

SOS... Need help and light

Post by Michel »

Hello, I wrote my first Medical Expert system in 80's... Mix of Turbo Prolog and Turbo C and tistributed by "Faculté des Sciences de Paris".

I need help about my new ES, a new medical one.

1) How can I create a list of lists, aka pathogie :"string name", "symbols remedies" and, then, a list of such a compound facts ?

2) How can I access and show a specific list of those above, progammaticaly, from a clause in response at a selected other list of proposed diseases.

I spend many hours reading and testing samples, some with success, but now I don't obtain other results than "compile errors". Every things is fine but not in the second part of the code...

It is probably very simple, but I do prefer my old "C" programming usage 😉.

Regards, Michel ( ..... from CĂŽte d'Azur, France )

Code: Select all

% Copyright Michel Berr   implement consult inherits formWindow     open core, vpiDomains   facts     sexe : integer := erroneous.     age : integer := erroneous.     patho : integer := erroneous.     /*     *     */     pathoWife : string* :=         [             "GĂ©nĂ©ralitĂ©s...",             "Psychisme...",             "SystĂšme nerveux...",             "Digestion - mĂ©tabolisme...",             "Respiration...",             "Coeur - Vaisseaux - Sang...",             "Reins - Voies urinaires...",             "Rhumatisme - Os - Muscles...",             "GynĂ©cologie...",             "Endocrinologe...",             "Nez - Gorge - Oreilles - Yeux...",             "Peau...",             "Maladies infectieuses..."         ].     pathoMale : string* :=         [             "GĂ©nĂ©ralitĂ©s...",             "Psychisme...",             "SystĂšme nerveux...",             "Digestion - mĂ©tabolisme...",             "Respiration...",             "Coeur - Vaisseaux - Sang...",             "Reins - Voies urinaires...",             "Rhumatisme - Os - Muscles...",             "GĂ©nital Homme...",             "Endocrinologe...",             "Nez - Gorge - Oreilles - Yeux...",             "Peau...",             "Maladies infectieuses..."         ].   clauses     display(Parent) = Form :-         Form = new(Parent),         Form:show().   clauses     new(Parent) :-         formWindow::new(Parent),         generatedInitialize(),         RadioGroup = radioButtonGroup_ctl:getRadioButtonGroup(),         RadioGroup:addSelectionChangedListener(groupListener),         ageChoice_ctl:addList(["Nourrisson", "Enfant", "Adolescent", "Jeune adulte", "Adulte", "Senior"]),         ageChoice_ctl:selectAt(0, false),         consultationCtl:addList(["DĂ©finir le sexe et l'Ăąge."]),         consultationCtl:selectAt(0, true).   predicates     onConsultationCtlMouseDbl : window::mouseDblListener. clauses     onConsultationCtlMouseDbl(_Source, _Point, _ShiftControlAlt, _Button) :-         patho := consultationCtl:tryGetSelectedIndex(),         !,         Symptoms = symptoms::new(This),         Symptoms:show(),         Symptoms:setText("Static text 2"),         symptoms::populateList("my test", age).       onConsultationCtlMouseDbl(_Source, _Point, _ShiftControlAlt, _Button).   predicates     onAgeChoiceSelectionChanged : listControl::selectionChangedListener. clauses     onAgeChoiceSelectionChanged(_Source) :-         consultationCtl:clearAll(),         age := ageChoice_ctl:tryGetSelectedIndex(),         !,         if _F = notErroneous(sexe) then             setPatientProfile(sexe, age)         end if.       onAgeChoiceSelectionChanged(_).   predicates     groupListener : radioButtonGroup::selectionChangedListener. clauses     groupListener(_RadioGroup, SelectedButton) :-         enableGroup_ctl:getCheckedState() = checkButton::checked,         CompareResult = compare(SelectedButton:getText(), "♂"),         !,         if CompareResult = equal then             sexe := 1         else             sexe := 0         end if,         if _F = notErroneous(age) then             setPatientProfile(sexe, age)         end if.       groupListener(_, _).   predicates     setPatientProfile : (integer S, integer A). clauses     setPatientProfile(1, _) :-         consultationCtl:clearAll(),         !,         consultationCtl:addList(pathoMale).     setPatientProfile(0, _) :-         consultationCtl:clearAll(),         !,         consultationCtl:addList(pathoWife).       setPatientProfile(_, _).   % This code is maintained automatically, do not update it manually. facts     consultationCtl : listBox.     radioButtonGroup_ctl : groupBox.     wife_ctl : radioButton.     male_ctl : radioButton.     ageChoice_ctl : listEdit.     enableGroup_ctl : checkButton.   predicates     generatedInitialize : (). clauses     generatedInitialize() :-         setText("consult"),         setRect(vpiDomains::rct(1, 1, 141, 154)),         setDecoration(titlebar([frameDecoration::maximizeButton, frameDecoration::minimizeButton, frameDecoration::closeButton])),         setBorder(frameDecoration::noBorder),         setState([wsf_ClipSiblings, wsf_ClipChildren]),         menuSet(noMenu),         setFont(vpi::fontCreateByName("Verdana", 12)),         consultationCtl := listBox::new(This),         consultationCtl:setText("List Box"),         consultationCtl:setRect(vpiDomains::rct(4, 44, 136, 149)),         consultationCtl:addMouseDblListener(onConsultationCtlMouseDbl),         consultationCtl:setSort(false),         radioButtonGroup_ctl := groupBox::new(This),         radioButtonGroup_ctl:setText("Sexe"),         radioButtonGroup_ctl:setRect(vpiDomains::rct(4, 6, 60, 35)),         radioButtonGroup_ctl:setSize(56, 29),         GroupBox1_ctl = groupBox::new(This),         GroupBox1_ctl:setText("Age"),         GroupBox1_ctl:setRect(vpiDomains::rct(64, 6, 136, 35)),         wife_ctl := radioButton::new(radioButtonGroup_ctl),         wife_ctl:setText("♀"),         wife_ctl:setRect(vpiDomains::rct(5, -1, 27, 12)),         wife_ctl:setFont(vpi::fontCreateByName("Corbel", 20)),         male_ctl := radioButton::new(radioButtonGroup_ctl),         male_ctl:setText("♂"),         male_ctl:setRect(vpiDomains::rct(31, -1, 53, 12)),         male_ctl:setFont(vpi::fontCreateByName("Corbel", 20)),         ageChoice_ctl := listEdit::new(GroupBox1_ctl),         ageChoice_ctl:setRect(vpiDomains::rct(5, 3, 66, 16)),         ageChoice_ctl:setSort(false),         ageChoice_ctl:addSelectionChangedListener(onAgeChoiceSelectionChanged),         ageChoice_ctl:setText("..."),         enableGroup_ctl := checkButton::new(This),         enableGroup_ctl:setRect(vpiDomains::rct(14, 181, 64, 193)),         enableGroup_ctl:setVisible(false),         enableGroup_ctl:setChecked(true),         enableGroup_ctl:setEnabled(true). % end of automatic code   end implement consult

Code: Select all

% Copyright Michel Berr   implement symptoms inherits dialog     open         core,         vpiDomains % % %   facts     remedes : symbol*.   %pathoMain : string.symbol*. %PathoFull : pathoMain*. clauses     display(Parent) = Dialog :-         Dialog = new(Parent),         Dialog:show().   clauses     new(Parent) :-         dialog::new(Parent),         generatedInitialize(),         populateList("dddd", 2).   clauses     populateList(X, Y) :-         stdio::writef("----> %s ----- %d", X, Y),         %listBox_ctl:addList(["My List Box MVB","fffffffff"]),         %symptoms:staticText_ctl:setText("My text"),         stdio::writef("test").   predicates     onOkClick : button::clickResponder. clauses     onOkClick(_Source) = button::defaultAction.   % This code is maintained automatically, do not update it manually. facts     ok_ctl : button.     cancel_ctl : button.     listSymptoms_ctl : listBox.   predicates     generatedInitialize : (). clauses     generatedInitialize() :-         setText("symptoms"),         setRect(vpiDomains::rct(50, 40, 449, 350)),         setModal(true),         setDecoration(titlebar([frameDecoration::closeButton])),         ok_ctl := button::newOk(This),         ok_ctl:setText("&OK"),         ok_ctl:setPosition(172, 284),         ok_ctl:setSize(56, 16),         ok_ctl:defaultHeight := false,         ok_ctl:setAnchors([control::right, control::bottom]),         ok_ctl:setClickResponder(onOkClick),         cancel_ctl := button::newCancel(This),         cancel_ctl:setText("Cancel"),         cancel_ctl:setPosition(236, 284),         cancel_ctl:setSize(56, 16),         cancel_ctl:defaultHeight := false,         cancel_ctl:setAnchors([control::right, control::bottom]),         listSymptoms_ctl := listBox::new(This),         listSymptoms_ctl:setText("List Box"),         listSymptoms_ctl:setRect(vpiDomains::rct(36, 38, 370, 270)),         StaticText_ctl = textControl::new(This),         StaticText_ctl:setText("Static text"),         StaticText_ctl:setRect(vpiDomains::rct(46, 6, 260, 28)). % end of automatic code   end implement symptoms
User avatar
Thomas Linder Puls
VIP Member
Posts: 1482
Joined: 28 Feb 2000 0:01

Re: SOS... Need help and light

Post by Thomas Linder Puls »

Hi Michel.

If I understand the problem correctly, the it sounds like you should use a map on the outer level and a list or set at inner level. (I will use English terms instead of French).

A map is a "table" which maps keys into values. You want to map a certain pathology into some remedies.

Given a certain pathology you want to look it up in the map to find the associated remedies.

Here are some domain definitions:

Code: Select all

domains     remedies = string*.     remedyTable = mapM{string Pathology, remedies Remedies}.
The first line defines "remedies" as a list of strings, i.e. a list of remedies. The second line defines "remedyTable" as a map from string (Pathology) to remedies (Remedies).

The "M" in mapM means that the map is modifiable, so we can update it with our data.

Let us have a remedyTable in a fact variable:

Code: Select all

facts    remedyTable : remedyTable := mapM_redBlack::new().
I have initialized it to a new (empty) mapM_redBlack object.

Now we can insert entries in the table (I suggest using a less hard coded to insert the data, but for now we will just hardcode it).

Code: Select all

predicates     initializeRemedyTable : (). clauses     initializeRemedyTable() :-         remedyTable:set("heart", ["digogxin", "carvedilol", ...]),         ...
The predicate above inserts a list of remedies for "heart" conditions. I don't know if this is what you have in mind, but I guess you can adjust it to your data.

Given a pathology we can try to obtain an associated list of remedies like this:

Code: Select all

predicates     tryGetRemedies : (string Pathology) -> remedies Remedies determ. clauses     tryGetRemedies(Pathology) = remedyTable:tryGet(Pathology).
I hope this gives you a starting point for solving your problem.

You can read more details about "collections" here: Collection library.
Regards Thomas Linder Puls
PDC
Michel
Posts: 2
Joined: 8 Nov 2025 17:17

Re: SOS... Need help and light

Post by Michel »

Thanks...

"BRAVO"!!!! It is exactly what I have in mind. I worked some years ago with Nasa CLIPS, revisited to work with UNIX ( the defunct Unixware :-( ) and the Motif library to test an expert system, on line, running on a server using Tarentella... Worked fine but, now, it is mandatory to use MS Window.

I leave sadly "C" to work with VIP : a very, very fine tool and compiler but hard to fully understand for a beginner with OOP like me.

Best regards, Michel