% --------------------------------------------------------------------------
%   FILE:       TOPLEVEL.PL
%   AUTHOR:     Tim Duncan
%   UPDATED:    Mon Aug  3 15:23:31 BST 1987
%   PURPOSE:    Toplevel, data collection etc for ATTENDING
% --------------------------------------------------------------------------


:- op(100,fx,*).
:- op(100,xfy,:).



/* go/0
Runs ATTENDING using test data. Debugging purposes.
eg: this version generates only the final section.               
*/

go :-
    init_data,
;;;    get_testdata,
;;;    aug([[Gen,Intub,Maint,Induct],Premed]), % do maintenance only
;;;    discuss_maintenance(Maint,Text/[]),
;;;    aug(X),
    minors(M),
    recorda(minors,M,_),
    good_techs(G),
    recorda(good_techs,G,_),
;;;    gencrit(X),
    discuss_minors.
;;;    flatten(Text,Out),
;;;    runoff(Out), nl.


/* The main predicate which runs the whole show. */

attending :-
    intro,
    init_data,
    initenv,
    get_data,   % get data about patient's medical condition
    separator,
    runoff([*cap,please,outline,an,anasthetic,plan,:,*nl]),
    get_plan(anes,PAT),     % get proposed treatment plan
    recorda(pat,PAT,_),
    plan_summary(PAT,Plan), % summarise user's plan
    separator,
    runoff([*cap,you,have,selected,:,*nl,*nl|Plan]),
    separator,
    augment_tree(anes,Risk,PAT,AUG), % analyse risks and augment tree
    recorda(aug,AUG,_), !,
    gencrit(AUG),                    % generate the critique                     
    separator.


/* Some blurb to introduce the system and make a disclaimer */

intro :-  separator,
    tab(19), write('*** ATTENDING ***'), nl, nl,
    write('A Computer System which Critiques an Anaesthetic Management Plan.'), nl,
    write('A Re-implementation in Prolog, based on the program by Perry Miller.'), nl,
    nl,
    write('This program is for demonstration purposes only, and no reliance'), nl,
    write('should be placed on the medical knowledge contained in it.'), nl,
    separator.



separator :-
    runoff([*nl,
'-------------------------------------------------------------------------',
    *nl]).





/* -------------------- INITIAL DATA COLLECTION ----------------------- */



init_data :- record_init(500).      % initialise record data structures



/* Display current data, for debugging purposes. */

data :- data(_).

data(K) :- datakeys(KL), member(K,KL),
    recorded(K,V,_), write(K), write(' ::: '), write(V),nl,fail.
data(K).

datakeys([patient,risk,block,minors,good_techs,text,pat,aug]).


/*
A failure-driven loop gets details of the questions
that must be asked (which are stored in pdata/3),
presents a menu, and adds the data to the database.
*/

get_data :-
    pdata(Question,Display,Menu),
    choose(Items,Question,Display,Menu),
    add_data(patient,Items),
    fail.
get_data.



/* add_data/2
Mode: add_data(+,+)
Args: add_data(K,V)
Add a list of data items (V) to the database under
the key (K), and forward chain on them.
*/

add_data(K,[]) :- !.
add_data(K,[n/a|T]) :- !,       % ignore N/A
    add_data(K,T).
add_data(K,[H|T]) :-
    recorda(K,H,_),
    forward_chain(K,H), !,
    add_data(K,T).
add_data(K,H) :-
    recorda(K,H,_),
    forward_chain(K,H), !.


/* update/2
Update or create the data stored under Key.
Called by setminors/1 in GENCRIT.PL
*/

update(Key,Val) :-
    ( recorded(Key,Old,Rf),
      erase(Rf)
    ; null(Old) ),
    recorda(Key,[Val|Old],_), !.




/* forward_chain/2
Forward chain on an item of data. That is, if it is a
medical problem pull out the relevant PMF and add any
risks to the database. In fact the risks must also be
augmented with the 'context' - ie. the name of the
medical problem. The second clause deals with data
which effectively 'blocks' an arc on the ADN.
*/

forward_chain(patient,Problem) :-
    pmframe(Problem,Principles,Risks),
    member(risk(Arc,Risk,Desc),Risks),          % adding the context
    add_data(risk,risk(Arc,Risk,[context(Problem)|Desc])),
    fail.
forward_chain(patient,Problem) :-
    op_block(Problem,Arclist),
    member(Arc,Arclist),
    add_data(block,[blocked(Arc)]),
    fail.
forward_chain(_,_).




/* ----------------- QUESTIONS TO BE ASKED --------------------------- */


/* pdata(Question,Display_menu,Return_menu). */

pdata(['Has patient suffered acute trauma or hemorrhage?'],
    [[yes],[no]],
    [acute_trauma, n/a]).

pdata(['Do you consider the patient to have a full stomach?'],
    [[yes],[no]],
    [full_stom, n/a]).

pdata(['Is the patient potentially hypovolemic?'],
    [[yes],[no]],
    [hypovolemia, n/a]).

pdata(['Please specify any other problems from this list:'],
    [[none],
     [asthma,
      [liver,disease],
      [chronic,renal,failure],
      [high,blood,pressure],
      [a,prior,stroke],
      [coronary,artery,disease],
      [a,penetrating,eye,wound],
      [an,abdominal,aortic,aneurysm],
      [an,oesophageal,hemorrhage],
      [increased,*allcaps,icp],
      [a,difficult,airway],
      [facial,trauma],
      [an,unstable,neck],
      [a,cerebral,aneurysm],
      [cartoid,disease],
      coagulopathy,
      myasthenia,
      hyperkalemia,
      [morbid,obesity],
      [a,bowel,obstruction],
      [*allcaps,copd],
      [history,of,*allcaps,maoi,treatment],
      [upper,airway,bleeding],                  % Miller missed these
      [tachycardia],
      [a,history,of,pat],
      [wpw],
      [pregnancy],
      [intoxication] ]],
    [n/a, asthma, liver_disease, crf, hbp, cva, cad, pene_eye, aaa,
    esoph_bleed, increased_icp, difficult_aw, facial_trauma,
    unstable_neck, cerebral_aneur, cartoid_dis, coagulopathy, myasthenia,
    hyperkalemia, morbid_obesity, bowel_obstr, copd, maoi,
    aw_bleed, tachycardia, hx_pat, wpw, pregnancy, intoxication
    ]).

pdata(['Please indicate surgical procedure:'],
    [ [[appendectomy]],
      [[an,abdominal,operation]],
      [[an,abdominal,aortic,aneurysm]],
      [[a,cartoid,endarterectomy]],
      [[cholecystectomy]],
      [[colectomy]],
      [[craniotomy]],
      [[an,operation,on,head,or,neck]],
      [[a,lower,extremity,operation]],
      [[tendon,repair]],
      [[a,total,hip,repair]],
      [[an,upper,extremity,operation]],
      [[an,eye,operation]]                  % Miller missed this
      ],
    [appendectomy, abdop, aortic_aneurysmectomy, cea, cholecystectomy,
    colectomy, craniotomy, headop, leop, tendon_repair, thr, ueop, eyeop]).
