Camellia Wunderbar
Camellia Wunderbar

Reputation: 5

Prolog compound statement returning multiple variables

I'm super new to Prolog, like, my professor assigned us a program and just asked us to watch a couple youtube videos. No lecture.

So anyway, here's the issue:

I'm supposed to create a pharmacist software that looks up drug interactions.

When I enter a specific drug, then Drug-variable, and Interaction-variable, I get the first drug and interaction in the list (of like, 100 drugs that interact with temazepam):

?- interacts(temazepam,Drug,Interaction).
Drug = thalidomide,
Interaction = neutropenia .

Part 1) How can I get every drug and its interaction from, say, temazepam?

Partial program listed below [because I have 1609 lines of drug interactions listed]:

interacts(X,Y,Interaction):-
Drug(X),
Drug(Y),
Interaction.

Interaction:-
Drug(X),
Drug(Y).

interacts(gatifloxacin,zolpidem,attempted_suicide).
interacts(gatifloxacin,zolpidem,insomnia).
interacts(gatifloxacin,warfarin,cardiac_decompensation).
interacts(gatifloxacin,isosorbide-5-mononitrate,arteriosclerotic_heart_disease).
interacts(gatifloxacin,rosiglitazone,hyperglycaemia).
interacts(gatifloxacin,bortezomib,hyperglycaemia).
interacts(gatifloxacin,mometasone,asthma).
interacts(gatifloxacin,cisplatin,hyperglycaemia).
interacts(gatifloxacin,cisplatin,bone_marrow_failure).
interacts(gatifloxacin,montelukast,difficulty_breathing).
interacts(temazepam,thalidomide,neutropenia).
interacts(temazepam,thalidomide,thrombocytopenia).
interacts(temazepam,timolol,drowsiness).
interacts(temazepam,tizanidine,acid_reflux).
interacts(temazepam,tizanidine,heart_attack).
interacts(temazepam,tolterodine,amnesia).

Part 2) I need to be able to list an interaction and get back every drug that caused it.

I guess just the side-effect then all drug interactions listed would be better than listing drug1+sideEffect = drug2.

Example:

?- interacts(Drug,Drug,amnesia).

Part 3) I should be able to enter a single drug, and get everything with interactions and everything with no interactions.

Example:

?- interacts(valacyclovir,Drug,Interaction).
Drug = zolpidem,
Interaction = anxiety

But for everything

Excuse me for the edits! Thanks so much in advance!

Upvotes: 0

Views: 922

Answers (1)

tas
tas

Reputation: 8140

You can use the built-in predicate findall/3 for that:

drug_allinteractions(Drug,AI) :-
    findall((D,I),interacts(Drug,D,I),AI).

The only goal of drug_allinteractions/2 is using findall/3 to query interacts/3 and put its second and third argument into the list AI as a tuple (D,I). Example query: Wich interacting drugs with what interaction-effect are known for gatifloxacin?:

   ?- drug_allinteractions(gatifloxacin,L).
L = [(zolpidem,attempted_suicide),(zolpidem,insomnia),(warfarin,cardiac_decompensation),(isosorbide-5-mononitrate,arteriosclerotic_heart_disease),(rosiglitazone,hyperglycaemia),(bortezomib,hyperglycaemia),(mometasone,asthma),(cisplatin,hyperglycaemia),(cisplatin,bone_marrow_failure),(montelukast,difficulty_breathing)]

Alternatively, if you just want to query interacts/3 and not write a program:

   ?- findall((D,I),interacts(gatifloxacin,D,I),AI).
AI = [(zolpidem,attempted_suicide),(zolpidem,insomnia),(warfarin,cardiac_decompensation),(isosorbide-5-mononitrate,arteriosclerotic_heart_disease),(rosiglitazone,hyperglycaemia),(bortezomib,hyperglycaemia),(mometasone,asthma),(cisplatin,hyperglycaemia),(cisplatin,bone_marrow_failure),(montelukast,difficulty_breathing)]

As for your added part 2): You can use findall on your original query:

   ?- findall((D1,D2),interacts(D1,D2,amnesia),AI).
AI = [(temazepam,tolterodine)]

Note, that unlike in your example I wrote two different variables D1 and D2 for the drugs, otherwise you are asking which drug has the interaction-effect amnesia with itself.

Considering your added part 3) I'm not entirely sure what you want. Your query reads: "Show me all drugs that interact with valacyclovir plus the associated effect". That is basically the same as your very first query, just for a different drug. You can query for all drugs in the relation interacts/3 interactively without showing the interacting drugs and the effects by:

   ?- interacts(D,_,_).
D = gatifloxacin ? ;
...

Or query for an entire list without duplicates by using setof/3:

   ?- setof(D1,D2^I^interacts(D1,D2,I),AI).
AI = [gatifloxacin,temazepam]

If you, however, try to find a list of drugs that are not interacting with a given drug, you can write a predicate, say drug_noninteractingdrug/2...

:- use_module(library(lists)).

drug_noninteractingdrug(D,NID) :-
    dif(D,NID),                        % D and NID are different
    setof(D2,D^interacts(D,D2,_),L),   % L ... all drugs interacting with D
    interacts(NID,_,_),                % NID ... drug...
    \+member(NID,L).                   % ... that is not in L

... and query this using setof/3:

   ?- setof(NID,drug_noninteractingdrug(gatifloxacin,NID),NIDs).
NIDs = [temazepam]

With your given minimal example this query of course only yields one drug. Note that you need to include library(lists) for the predicate member/2.

Upvotes: 1

Related Questions