Comorbidity Conflict Solver

Content and Instructions


This webpage contains the ASP code and instructions for running the comorbidity conflict solver, developed by Elie Merhej.
This program expands Zhang's implementation of solving conflicts that arise when multiple Computer Interpretable Guidelines (CIG) need to be used simultaneously to treat patients with comorbidity.

To run the ASP code, the ASP grounder gringo (version 3.0.4) and the ASP solver clasp (version 3.1.0) need to be installed.

ASP Program


The following is the ASP code for the comorbidity conflict solver.
The text in green marked by the symbol "%" contains comments about the code.
A text file named "progASP_comorbidity.txt" contains this ASP program and is available to download in the Download section.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Disease-specific facts
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% diseases
disease(du).
disease(tia).

% activity graphs of DU and TIA

% DU
ag(du,duAg).
cNode(duAg,du).

aNode(duAg,sa).
aNode(duAg,et).
aNode(duAg,ppi).
aNode(duAg,sc).
aNode(duAg,rs).

xNode(duAg,hpyTest).

xNode(duAg,ulcerHealed).

edge(duAg,du,sa).
edge(duAg,sa,hpyTest).
edge(duAg,et,ulcerHealed).
edge(duAg,ppi,ulcerHealed).

edge(duAg,hpyTest,et).
label(duAg,hpyTest,et,hpp).

edge(duAg,hpyTest,ppi).
label(duAg,hpyTest,ppi,hpn).

edge(duAg,ulcerHealed,sc).
label(duAg,ulcerHealed,sc,uh).

edge(duAg,ulcerHealed,rs).
label(duAg,ulcerHealed,rs,unh).

% TIA
ag(tia,tiaAg).
cNode(tiaAg,tia).

aNode(tiaAg,ec).
aNode(tiaAg,a).
aNode(tiaAg,ts).
aNode(tiaAg,pcs).
aNode(tiaAg,d).
aNode(tiaAg,nc).

xNode(tiaAg,hypCaemia).

xNode(tiaAg,fast).

xNode(tiaAg,neuSymResolved).

xNode(tiaAg,riskStroke).

edge(tiaAg,tia,hypCaemia).
edge(tiaAg,a,riskStroke).
edge(tiaAg,ts,nc).
edge(tiaAg,d,nc).

edge(tiaAg,hypCaemia,fast).
label(tiaAg,hypCaemia,fast,ha).

edge(tiaAg,hypCaemia,ec).
label(tiaAg,hypCaemia,ec,hp).

edge(tiaAg,fast,pcs).
label(tiaAg,fast,pcs,fn).

edge(tiaAg,fast,neuSymResolved).
label(tiaAg,fast,neuSymResolved,fp).

edge(tiaAg,neuSymResolved,a).
label(tiaAg,neuSymResolved,a,nsr).

edge(tiaAg,neuSymResolved,ts).
label(tiaAg,neuSymResolved,ts,nsnr).

edge(tiaAg,riskStroke,pcs).
label(tiaAg,riskStroke,pcs,rsn).

edge(tiaAg,riskStroke,d).
label(tiaAg,riskStroke,d,rse).

% mitigation opertators
mo(1).
moBD(1,tia).
moTD(1,du).
moPOC(1,a).
moPOC(1,sa).
moLHS(1,pos(a)).
moLHS(1,neg(d)).
moRHS(1,neg(a)).
moRHS(1,pos(cl)).
moToBeRemoved(1,sa).

mo(2).
moBD(2,tia).
moTD(2,du).
moPOC(2,a).
moPOC(2,sa).
moLHS(2,pos(a)).
moLHS(2,pos(d)).
moRHS(2,pos(a)).
moRHS(2,pos(d)).
moRHS(2,pos(ppi)).
moToBeRemoved(2,sa).

mo(3).
moBD(3,tia).
moTD(3,du).
moPOC(3,a).
moPOC(3,sa).
moLHS(3,pos(a)).
moLHS(3,neg(d)).
moRHS(3,pos(a)).
moRHS(3,pos(cy)).
moToBeRemoved(3,sa).

mo(4).
moBD(4,tia).
moTD(4,du).
moPOC(4,a).
moPOC(4,sa).
moLHS(4,pos(a)).
moLHS(4,neg(d)).
moRHS(4,pos(a)).
moRHS(4,pos(fl)).
moToBeRemoved(4,sa).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Drug interactions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

drug(cl). % clopidogrel
drug(ppi). % esomeprazole
drug(cy). % cyanocobalamin
drug(fl). % flibanserin
drug(a). % aspirin

interaction(cl,ppi,3). % clopidogrel - esomeprazole
interaction(cy,ppi,1). % cyanocobalamin - esomeprazole
interaction(fl,ppi,2). % flibanserin - esomeprazole
interaction(a,ppi,1). % aspirin - esomeprazole


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Patient information
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

patientInfo(hpyTest,hpn).
patientInfo(ulcerHealed,uh).

patientInfo(hypCaemia,ha).
patientInfo(fast,fp).
patientInfo(neuSymResolved,nsr).
% patientInfo(riskStroke,rsn).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% General procedure of repairing inconsistencies that arise between candidate treatments
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% find all possible candidate treatments
% define nodes and decision nodes
decisionNode(Ag,X) :- oNode(Ag,X).
decisionNode(Ag,X) :- xNode(Ag,X).

node(Ag,X) :- aNode(Ag,X).
node(Ag,X) :- cNode(Ag,X).
node(Ag,X) :- decisionNode(Ag,X).

% only decision nodes are allowed to have more than one outgoing edge
:- edge(Ag,X,Y1), edge(Ag,X,Y2), Y1 != Y2, not decisionNode(Ag,X).

% every edge in the graph can be selected as a candidate edge
candidateEdge(Ag,X,Y) :- edge(Ag,X,Y), not nCandidateEdge(Ag,X,Y).
nCandidateEdge(Ag,X,Y) :- edge(Ag,X,Y), not candidateEdge(Ag,X,Y).

% make sure both options of an xor decision node are not selected at the same time
:- candidateEdge(Ag,X,Y1), candidateEdge(Ag,X,Y2), Y1 != Y2, xNode(Ag,X).

% either select both incoming and outoing edges of an action node, or neither
:- node(Ag,X), aNode(Ag,Y), nCandidateEdge(Ag,X,Y), candidateEdge(Ag,Y,Z).
:- node(Ag,X), aNode(Ag,Y), candidateEdge(Ag,X,Y), nCandidateEdge(Ag,Y,Z).

% define leaf nodes
nLeafNode(Ag,X) :- node(Ag,X), node(Ag,Y), edge(Ag,X,Y).
leafNode(Ag,X) :- node(Ag,X), not nLeafNode(Ag,X).

% make sure at least 1 candidate treatment exists for every disease
% (at least 1 leaf node is reachable from context node)
reachable(Ag,X) :- cNode(Ag,Cn), candidateEdge(Ag,Cn,X).
reachable(Ag,Y) :- reachable(Ag,X), candidateEdge(Ag,X,Y).

candidateTreatmentExists(Ag) :- leafNode(Ag,X), reachable(Ag,X).

:- not candidateTreatmentExists(Ag), ag(D,Ag).

% make sure every node in a candidate treatment is reachable
nodeInTreatment(Ag,X) :- candidateEdge(Ag,X,Y).
nodeInTreatment(Ag,Y) :- candidateEdge(Ag,X,Y).

:- nodeInTreatment(Ag,X), not cNode(Ag,X), not reachable(Ag,X).

% make sure there are candidate edges that correspond to the patient information
:- decisionNode(Ag,X), nodeInTreatment(Ag,X), patientInfo(X,L), label(Ag,X,Y,L), not candidateEdge(Ag,X,Y).

% points of contention
poc(1).
pocAction(1,a).
pocAction(1,sa).

% check which action node is in a candidate treatment
actionInTreatment(D,X) :- nodeInTreatment(Ag,X), aNode(Ag,X), ag(D,Ag).

% mark every action node in a candidate treatment as "active"
activeAction(D,A) :- actionInTreatment(D,A).
activeAction(A) :- activeAction(D,A).

% a POC is active if all its actions are active
inactivePOC(PocID) :- not activeAction(A), pocAction(PocID,A).
activePOC(PocID) :- poc(PocID), not inactivePOC(PocID).

% find relevant MOs
% every action in moPOC part of an MO should be an action of an active POC
% the base disease and target disease of an MO should be relevant diseases
irrelevantMO(PocID,MoID) :- activePOC(PocID), mo(MoID), pocAction(PocID,A), not moPOC(MoID,A).
irrelevantMO(PocID,MoID) :- activePOC(PocID), mo(MoID), not disease(D), moBD(MoID,D).
irrelevantMO(PocID,MoID) :- activePOC(PocID), mo(MoID), not disease(D), moTD(MoID,D).
relevantMO(PocID,MoID) :- activePOC(PocID), mo(MoID), not irrelevantMO(PocID,MoID).

% find applicable MOs
% pos actions in LHS of an MO should be actions in treatment of base disease
% neg actions in LHS of an MO should not be actions in treatment of base disease
inapplicableMO(PocID,MoID) :- relevantMO(PocID,MoID), moLHS(MoID,pos(A)), moBD(MoID,D), not activeAction(D,A).
inapplicableMO(PocID,MoID) :- relevantMO(PocID,MoID), moLHS(MoID,neg(A)), moBD(MoID,D), activeAction(D,A).
applicableMO(PocID,MoID) :- relevantMO(PocID,MoID), not inapplicableMO(PocID,MoID).

% apply exactly 1 of the applicable MOs to eliminate a point of contention
applyMO(PocID,MoID) :- activePOC(PocID), applicableMO(PocID,MoID), not napplyMO(PocID,MoID).
napplyMO(PocID,MoID) :- activePOC(PocID), applicableMO(PocID,MoID), not applyMO(PocID,MoID).

appliedMOs(PocID,X) :- X = #count{applyMO(PocID,MoID)}, activePOC(PocID).

errorApplyingMo(PocID) :- appliedMOs(PocID,X), X < 1.
errorApplyingMo(PocID) :- appliedMOs(PocID,X), X > 1.

:- errorApplyingMo(PocID).

% modify both treatments based on the applied point of cotention
% treatment for target disease
solutionTreatment(TD,A) :- activeAction(TD,A), applyMO(PocID,MoID), moTD(MoID,TD), not moToBeRemoved(MoID,A).

% treatment for base disease
solutionTreatment(BD,A) :- applyMO(PocID,MoID), moBD(MoID,BD), moRHS(MoID,pos(A)).

occursIn(A,MoID) :- moLHS(MoID,pos(A)).
occursIn(A,MoID) :- moLHS(MoID,neg(A)).
occursIn(A,MoID) :- moRHS(MoID,pos(A)).
occursIn(A,MoID) :- moRHS(MoID,neg(A)).

solutionTreatment(BD,A) :- activeAction(BD,A), applyMO(PocID,MoID), moBD(MoID,BD), not occursIn(A,MoID).

% final consistency check for solution treatment (can we still find a point of contention?)
solutionAction(A) :- solutionTreatment(D,A).

ignorePOC(PocID) :- not solutionAction(A), pocAction(PocID,A).
pocFound(PocID) :- poc(PocID), not ignorePOC(PocID).

% no point of contentions are allowed in solution treatments
:- pocFound(PocID).

% sum the penalty from drug interactions in solution treatments
solutionDrug(X) :- solutionAction(X), drug(X).

solutionInteraction(X,Y,C) :- interaction(X,Y,C), solutionDrug(X), solutionDrug(Y).
interactionsPenalty(P) :- P = #sum[solutionInteraction(X,Y,C)=C].

% the best solution treatment is the treatment with the lowest interaction penalty
#minimize[interactionsPenalty(P)=P].


#hide.
%#show candidateTreatment(D,X).
%#show activePOC(PocID).
%#show relevantMO(PocID,MoID).
%#show applicableMO(PocID,MoID).
#show applyMO(PocID,MoID).
%#show solutionInteraction(X,Y,C).
#show interactionsPenalty(P).
#show solutionTreatment(D,A).

Note: "#show" statements can be modified to show/hide literals in the answer sets of the program.

Output


To run this ASP program, the following command should be executed:

gringo progASP_comorbidity.txt | clasp 0 --quiet=1 --opt-mode=optN

This tells gringo to ground the program, and tells clasp to solve the grounded program, and output all possible solutions that have the best optimization criteria (i.e. that minimize the interactions penalty).

The output of this program is the following:

clasp version 3.1.0
Reading from stdin
Solving...
Answer: 1
applyMO(1,2) solutionTreatment(tia,nc) solutionTreatment(tia,d) solutionTreatment(tia,a) solutionTreatment(du,sc) solutionTreatment(du,ppi) solutionTreatment(tia,ppi) interactionsPenalty(1)
Optimization: 1
OPTIMUM FOUND

Models : 2
Optimum : yes
Optimization : 1
Calls : 1
Time : 0.002s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s

The program found that there is only one treatment with the lowest interactions penalty (penalty = 1).
This treatment is {ppi, sc, a, d, nc}, found by applying mitigation operator 2.

Note: The following command "gringo progASP_comorbidity.txt | clasp 0 --opt-mode=enum" will output all the answer sets with their respective optimization value (for ranking from best to worst or vice versa)
Note 2: Commenting out patient information, drug interactions and mitigation operators create multiple scenarios.

Download


This ASP program is available to download here: progASP_comorbidity.txt



Website  Computational Web Intelligence TeamComputational Web Intelligence