% NUTRIMINE: A Micro-Nutrient Knowledge Base (Source)            06-Aug-98
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% http://www.dfki.uni-kl.de/~vega/relfun+/nutrimine.rfp      (eg *.script)
% http://www.dfki.uni-kl.de/~vega/relfun+/nutrimine.rfp.html (eg *.script.html)
% [the *.html versions produced by a txt2html adaptation have active URLs etc.]

% Harold Boley                                   DFKI/Univ. Kaiserslautern
% boley@informatik.uni-kl.de



% The micro nutrients to be included into the NUTRIMINE knowledge base (KB)
% encompass certain vitamins, provitamins, and minerals. NUTRIMINE extends
% earlier work on Web-released materials KBs running in RELFUN (ELEMENTS and
% RTPLAST, see http://www.dfki.uni-kl.de/~vega/relfun.html).
% The knowledge formalized below is being used primarily for KB research. It
% is not currently intended to provide any dietary or medical recommendation.
% But NUTRIMINE may encourage readers/users to search for more information
% and form their own opinions. Thus, we do not go into the debate about
% nutritional supplements: yes/no? for which individuals? when? what doses?
% (e.g., may Beta-Carotene pills be harmful for some groups such as smokers?
% for CARET Study see http://www.thorne.com/townsend/may/blandmay96.html).
% Some future NUTRIMINE could provide a KB as one basis for (pro or cons)
% arguments for such debates. The author welcomes any feedback, especially
% concerning a possible collaborative, WWW-distributed KB development of
% NUTRIMINE. Two specific caveats: some of the current algorithms provide
% only first approximations (e.g. dose ranges are reduced to their means),
% and the basic data are quite uncertain (e.g. freshness and micro-nutrient
% content of raw food may vary).
% While this NUTRIMINE version uses a mostly functional RELFUN style, it is
% transformable into a purely relational RELFUN style via the relationalize 
% command (as shown in nutrimine.script); except for NUTRIMINE's higher-order
% aspects, this amounts to Horn logic or -- via the rfp2pl transformation --
% to PROLOG. The relational-style NUTRIMINE version thus contains an initial
% nucleus of the first-order (Horn-logic) KBs discussed in our concept paper
% "Knowledge Bases in the World Wide Web: A Challenge for Logic Programming"
% (see URL http://www.dfki.uni-kl.de/~boley/lpwww/lpwww-emem.ps).
% Towards the end of the below KB, early results of a collaborative effort
% with the Univ. Twente are integrated. We start the KB with links to pages
% from the Univ. Koeln.



% Chemical Structure and Pharmaceutical "ACE" Info by Bad Heilbrunner

% The following bookmarks link to the "ACE" pages of the Bad Heilbrunner
% Selbstmedikationsdatenbank (http://www.tee.org/), constructed, in German,
% under the leadership of Klaus Klein by the Forschungsstelle fuer
% Gesundheitserziehung, Univ. Koeln.

bmark(vitamin-a) :- "Mostly discusses Vitamin-A rather than Beta-Carotene"
                    & "http://www.tee.org/BHSD/bhsd159.html".

bmark(vitamin-c) :& "http://www.tee.org/BHSD/bhsd164.html".

bmark(vitamin-e) :& "http://www.tee.org/BHSD/bhsd166.html".



% How Much (mg per kg) of which Nutrients is Contained in Some Food?

nutramount(Food) :& tupof(Amount .= nutrifood(Nutrient,Food),
                          [Nutrient,Amount]).


% How Much (mg) of which Nutrients is Contained in Some Portion (kg) of Food?

nutraport(Food,Portion) :& map[multsecond[Portion]](nutramount(Food)).


% What Nutrients are Contained in Some Meal (Set-as-List of Portioned Foods)?

nutraddup([]) :& [].
nutraddup([[Food,Portion]|Mealrest]) :&
  compunion[add-measures](nutraport(Food,Portion),nutraddup(Mealrest)).



% How Much Would I Have to Eat of Some Food for a Recommended Nutrient Dose?

nutreat(Nutrient,Food,Individual,Recommender) :-
  % foodnutrients mg  /  1 kg  =  dosenutrients mg/d  /  eat kg/d
  % eat kg/d  =  (dosenutrients mg/d  *  1 kg)  /  foodnutrients mg
  mg/kg[Nutrifood] .= nutrifood(Nutrient,Food),
  mg/d[Nutridose]  .= nutridose(Nutrient,Individual,Recommender),
  Eat .= /(meanrange(Nutridose),   % replace possible range by its mean
           *(Nutrifood,1.0)) &     % enforce floating-point number
  [Individual,for,mg/d[Nutridose],Nutrient,following,Recommender,
   eat,kg/d[Eat],of,mg/kg[Nutrifood],Food].



% Compute Set-as-List Union While Applying Operation to Second Pair Elements

compunion[Operation]([],M) :& M.
compunion[Operation]([P|R],M) :&
 compinsert[Operation](P,compunion[Operation](R,M)).

compinsert[Operation]([Element,Weight],[]) :& [[Element,Weight]].
compinsert[Operation]([Element,Weight1],[[Element,Weight2]|S]) !&
 tup(tup(Element,Operation(Weight1,Weight2))|S).
compinsert[Operation]([Element1,Weight1],[[Element2,Weight2]|S]) :&
 tup([Element2,Weight2]|
     compinsert[Operation]([Element1,Weight1],S)).


% Transform a Range (Interval) Term into the Mean of its Two Boundaries

meanrange(X) :- numberp(X) & X.
meanrange(range[From,To]) :& /(+(From,To),2).


% Arithmetics over Unit-Measured Magnitudes

add-measures(U[M1],U[M2]) :- unit(U), S .= +(M1,M2) & U[S].

multsecond[kg[Factor]]([Nutrient,mg/kg[Magnitude]]) :-
  Prod .= *(Factor,Magnitude) & [Nutrient,mg[Prod]].



% Food Examples Containing Micro Nutrients such as (Pro)Vitamins

% nutrifood gives the mg/kg amount of a nutrient in some (fresh raw) food


% Fruits+Vegetables Containing Beta Carotene (to be Extended)

nutrifood(beta-carotene,strawberry) :& mg/kg[0.3].

nutrifood(beta-carotene,spinach) :& mg/kg[8.0].
nutrifood(beta-carotene,carrot) :& mg/kg[11.3].


% Fruits+Vegetables Containing Vitamin C (to be Extended)

nutrifood(vitamin-c,strawberry) :& mg/kg[620].
nutrifood(vitamin-c,acerola) :& mg/kg[13000].

nutrifood(vitamin-c,broccoli) :& mg/kg[1100].


% Fruits+Vegetables Containing Vitamin E (to be Extended)

nutrifood(vitamin-e,pea) :& mg/kg[30].
nutrifood(vitamin-e,hazelnut) :& mg/kg[210].



% Recommended Daily Doses (Four Opinions: Consult Your Doctor to Form Your Own)
% DGE:     Recommendation of the Deutsche Gesellschaft fuer Ernaehrung
%          (http://www.vitalstoffe.de/zufuhrempfehlung.shtml)
% (US)RDA: (United States) Recommended Dietary Allowance
%          (http://www.mediconsult.com/noframes/vitamins/shareware/rdirda/)
% BS:      Prophylactic Recommendation of Wolfgang Bayer and Karlheinz Schmidt
% COOPER:  Antioxidant Recommendation of Kenneth H. Cooper

% nutridose gives the mg/d of a nutrient for an individual as by a recommender


% Beta-Carotene Dose

nutridose(beta-carotene,I,dge)   :- man(I)       & mg/d[1].

nutridose(beta-carotene,I,usrda) :- woman(I)     & mg/d[2.4].
nutridose(beta-carotene,I,usrda) :- man(I)       & mg/d[3].
nutridose(beta-carotene,I,usrda) :- child(I)     & mg/d[1.5].

nutridose(beta-carotene,_,bs)                   :& mg/d[range[5,15]].

nutridose(beta-carotene,_,cooper)               :& mg/d[range[6,30]].


% Vitamin-C Dose

nutridose(vitamin-c,I,dge)       :- man(I)       & mg/d[75].

nutridose(vitamin-c,I,usrda)     :- adult(I)     & mg/d[30].
nutridose(vitamin-c,I,usrda)     :- child(I)     & mg/d[45].

nutridose(vitamin-c,_,bs)                       :& mg/d[range[50,200]].

nutridose(vitamin-c,_,cooper)                   :& mg/d[range[500,3000]].


% Vitamin-E Dose

nutridose(vitamin-e,I,dge)       :- man(I)       & mg/d[12].

nutridose(vitamin-e,I,usrda)     :- woman(I)     & mg/d[12].
nutridose(vitamin-e,I,usrda)     :- man(I)       & mg/d[15].
nutridose(vitamin-e,I,usrda)     :- child(I)     & mg/d[7].

nutridose(vitamin-e,_,bs)                       :& mg/d[range[10,100]].

nutridose(vitamin-e,_,cooper)                   :& mg/d[range[200,1200]].



% Sort Predicates and Individual Applications

adult(I) :- woman(I).
adult(I) :- man(I).

man(linus).

unit(mg).
unit(kg).



% Self-Normalizing Data Structures

g(N) :- D .= /(N,1000.0) & kg[D].

lb(N) :- D .= /(N,2.0) & kg[D].



% Utilities to be Preloaded from prelude.rfp

map[Fct]([]) :- & [].
map[Fct]([H|T]) :- & tup(Fct(H)|map[Fct](T)).



% Molecule Representation of "ACE" Nutrients Generated by Paul van der Vet

% Paul van der Vet (http://wwwis.cs.utwente.nl:8080/~vet/), Univ. Twente,
% has produced a program and this docu part that let users prepare molecule
% representations by drawing the molecules like a chemist would. He uses
% the ChemDraw (registered trademark of CambridgeSoft Corporation) program
% to reproduce the drawing plus a file in connection table format. Paul has
% implemented a DCG-style Prolog program to convert the connection table
% into a list of atoms and bonds. This information is written to a file in
% the form of a fact:

% molecule( Name, Format, ListOfAtoms, ListOfBonds ).

% where:

% - Name is some atom to name the thing. He used ascorbic_acid
% (vitamin C), beta_carotene (a precursor of vitamin A) and
% alpha_tocopherol (one of the vitamin E group). By the way, the files
% have the same base names.

% - Format is introduced because chemists almost always leave out the
% hydrogen atoms. As long as certain precautions are observed, this
% causes no ambiguities. Paul's program produces both the representation
% without H's (Format = mol) and that with all H-atoms and bonds to
% H-atoms inserted (Format = molh). Both versions are present in each of
% the files.
% At a later stage, he also wants to introduce a third format, radical, to
% be able to specify molecules with variant parts like alpha-, beta-,
% gamma-, and delta-tocopherol.

% - ListOfAtoms is a list with members of the form
% Prolog: atom( Label, AtNr )            Relfun:  atom[ Label, AtNr ]
% Label is a unique label within the molecule, and AtNr is the element's
% atomic number. The constructor "atom" is used purely for readability.

% - ListOfBonds is a list with members of the form
% Prolog: bond( Label1, Label2, Order )  Relfun: bond[ Label1, Label2, Order ]
% Label1 and Label2 are, as you guessed, the labels of the atoms connected
% by the bond. Order is the bond order as defined by a chemist, i.e., "1"
% for a single bond, "2" for a double bond, and "3" for a triple bond.
% The bond order of aromatic bonds ought to be "1.5", but following
% chemical custom we model aromatic bonds as alternating single and double
% bonds. Like for the atoms, the constructor "bond" serves readability.

% Markus Perling (perling@dfki.uni-kl.de), DFKI/Univ. Kaiserslautern, did
% the transcription of the PROLOG form into the final RELFUN form below
% (only the molh version will be given). He also adapted the txt2html tool
% for HTMLizing the original text form of NUTRIMINE.


% Beta-Carotene

molecule(beta_carotene, molh,
     [
   atom[1,6], atom[2,6], 
   atom[3,6], atom[4,6], 
   atom[5,6], atom[6,6], 
   atom[7,6], atom[8,6], 
   atom[9,6], atom[10,6], 
   atom[11,6], atom[12,6], 
   atom[13,6], atom[14,6], 
   atom[15,6], atom[16,6],     
   atom[17,6], atom[18,6], 
   atom[19,6], atom[20,6], 
   atom[21,6], atom[22,6], 
   atom[23,6], atom[24,6], 
   atom[25,6], atom[26,6], 
   atom[27,6], atom[28,6], 
   atom[29,6], atom[30,6], 
   atom[31,6], atom[32,6], 
   atom[33,6], atom[34,6], 
   atom[35,6], atom[36,6], 
   atom[37,6], atom[38,6], 
   atom[39,6], atom[40,6], 
   atom[41,1], atom[42,1], 
   atom[43,1], atom[44,1], 
   atom[45,1], atom[46,1], 
   atom[47,1], atom[48,1], 
   atom[49,1], atom[50,1], 
   atom[51,1], atom[52,1], 
   atom[53,1], atom[54,1], 
   atom[55,1], atom[56,1], 
   atom[57,1], atom[58,1], 
   atom[59,1], atom[60,1], 
   atom[61,1], atom[62,1], 
   atom[63,1], atom[64,1], 
   atom[65,1], atom[66,1], 
   atom[67,1], atom[68,1], 
   atom[69,1], atom[70,1], 
   atom[71,1], atom[72,1], 
   atom[73,1], atom[74,1], 
   atom[75,1], atom[76,1], 
   atom[77,1], atom[78,1], 
   atom[79,1], atom[80,1], 
   atom[81,1], atom[82,1], 
   atom[83,1], atom[84,1], 
   atom[85,1], atom[86,1], 
   atom[87,1], atom[88,1], 
   atom[89,1], atom[90,1], 
   atom[91,1], atom[92,1], 
   atom[93,1], atom[94,1], 
   atom[95,1], atom[96,1]
     ],
     [
   bond[1,2,1], bond[2,3,1], 
   bond[3,4,1], bond[4,5,2], 
   bond[5,6,1], bond[1,6,1], 
   bond[6,7,1], bond[6,8,1], 
   bond[4,9,1], bond[5,10,1], 
   bond[10,11,2], bond[11,12,1], 
   bond[12,13,2], bond[12,14,1], 
   bond[13,15,1], bond[15,16,2], 
   bond[16,17,1], bond[17,18,2], 
   bond[17,19,1], bond[18,20,1], 
   bond[20,21,2], bond[21,22,1], 
   bond[22,23,2], bond[23,24,1], 
   bond[23,25,1], bond[24,26,2], 
   bond[26,27,1], bond[27,28,2], 
   bond[28,29,1], bond[28,30,1], 
   bond[29,31,2], bond[31,32,1], 
   bond[32,33,1], bond[33,34,1], 
   bond[34,35,1], bond[35,36,1], 
   bond[36,37,1], bond[32,37,2], 
   bond[37,38,1], bond[33,39,1], 
   bond[33,40,1], bond[1,41,1], 
   bond[1,42,1], bond[2,43,1], 
   bond[2,44,1], bond[3,45,1], 
   bond[3,46,1], bond[7,47,1], 
   bond[7,48,1], bond[7,49,1], 
   bond[8,50,1], bond[8,51,1], 
   bond[8,52,1], bond[9,53,1], 
   bond[9,54,1], bond[9,55,1], 
   bond[10,56,1], bond[11,57,1], 
   bond[13,58,1], bond[14,59,1], 
   bond[14,60,1], bond[14,61,1], 
   bond[15,62,1], bond[16,63,1], 
   bond[18,64,1], bond[19,65,1], 
   bond[19,66,1], bond[19,67,1], 
   bond[20,68,1], bond[21,69,1], 
   bond[22,70,1], bond[24,71,1], 
   bond[25,72,1], bond[25,73,1], 
   bond[25,74,1], bond[26,75,1], 
   bond[27,76,1], bond[29,77,1], 
   bond[30,78,1], bond[30,79,1], 
   bond[30,80,1], bond[31,81,1], 
   bond[34,82,1], bond[34,83,1], 
   bond[35,84,1], bond[35,85,1], 
   bond[36,86,1], bond[36,87,1], 
   bond[38,88,1], bond[38,89,1], 
   bond[38,90,1], bond[39,91,1], 
   bond[39,92,1], bond[39,93,1], 
   bond[40,94,1], bond[40,95,1], 
   bond[40,96,1]
     ]
  ).


% Vitamin-C

molecule(ascorbic_acid, molh,
     [
   atom[1,6], atom[2,6], 
   atom[3,6], atom[4,8], 
   atom[5,6], atom[6,6], 
   atom[7,8], atom[8,8], 
   atom[9,8], atom[10,6], 
   atom[11,8], atom[12,8], 
   atom[13,1], atom[14,1], 
   atom[15,1], atom[16,1], 
   atom[17,1], atom[18,1], 
   atom[19,1], atom[20,1]
     ],
     [
   bond[1,2,2], bond[2,3,1], 
   bond[3,4,1], bond[4,5,1], 
   bond[1,5,1], bond[3,6,1], 
   bond[1,7,1], bond[2,8,1], 
   bond[5,9,2], bond[6,10,1], 
   bond[6,11,1], bond[10,12,1], 
   bond[3,13,1], bond[6,14,1], 
   bond[7,15,1], bond[8,16,1], 
   bond[10,17,1], bond[10,18,1], 
   bond[11,19,1], bond[12,20,1]
     ]
  ).


% Vitamin-E

molecule(alpha_tocopherol, molh,
     [                         
   atom[1,6], atom[2,6], 
   atom[3,6], atom[4,6], 
   atom[5,6], atom[6,6], 
   atom[7,8], atom[8,6], 
   atom[9,6], atom[10,6], 
   atom[11,6], atom[12,6], 
   atom[13,6], atom[14,6], 
   atom[15,6], atom[16,6], 
   atom[17,6], atom[18,6], 
   atom[19,6], atom[20,6], 
   atom[21,6], atom[22,6], 
   atom[23,6], atom[24,6], 
   atom[25,6], atom[26,6], 
   atom[27,6], atom[28,6], 
   atom[29,6], atom[30,6], 
   atom[31,8], atom[32,1], 
   atom[33,1], atom[34,1], 
   atom[35,1], atom[36,1], 
   atom[37,1], atom[38,1], 
   atom[39,1], atom[40,1], 
   atom[41,1], atom[42,1], 
   atom[43,1], atom[44,1], 
   atom[45,1], atom[46,1], 
   atom[47,1], atom[48,1], 
   atom[49,1], atom[50,1], 
   atom[51,1], atom[52,1], 
   atom[53,1], atom[54,1], 
   atom[55,1], atom[56,1], 
   atom[57,1], atom[58,1], 
   atom[59,1], atom[60,1], 
   atom[61,1], atom[62,1], 
   atom[63,1], atom[64,1], 
   atom[65,1], atom[66,1], 
   atom[67,1], atom[68,1], 
   atom[69,1], atom[70,1], 
   atom[71,1], atom[72,1], 
   atom[73,1], atom[74,1], 
   atom[75,1], atom[76,1], 
   atom[77,1], atom[78,1], 
   atom[79,1], atom[80,1], 
   atom[81,1]
     ],
     [
   bond[1,2,2], bond[2,3,1], 
   bond[3,4,2], bond[4,5,1], 
   bond[5,6,2], bond[1,6,1], 
   bond[4,7,1], bond[7,8,1], 
   bond[8,9,1], bond[9,10,1],  
   bond[5,10,1], bond[6,11,1], 
   bond[2,12,1], bond[3,13,1], 
   bond[8,14,1], bond[8,15,1], 
   bond[15,16,1], bond[16,17,1], 
   bond[17,18,1], bond[18,19,1], 
   bond[18,20,1], bond[19,21,1], 
   bond[21,22,1], bond[22,23,1], 
   bond[23,24,1], bond[23,25,1], 
   bond[24,26,1], bond[26,27,1], 
   bond[27,28,1], bond[28,29,1], 
   bond[28,30,1], bond[1,31,1], 
   bond[9,32,1], bond[9,33,1], 
   bond[10,34,1], bond[10,35,1], 
   bond[11,36,1], bond[11,37,1], 
   bond[11,38,1], bond[12,39,1], 
   bond[12,40,1], bond[12,41,1], 
   bond[13,42,1], bond[13,43,1], 
   bond[13,44,1], bond[14,45,1], 
   bond[14,46,1], bond[14,47,1], 
   bond[15,48,1], bond[15,49,1], 
   bond[16,50,1], bond[16,51,1], 
   bond[17,52,1], bond[17,53,1], 
   bond[18,54,1], bond[19,55,1], 
   bond[19,56,1], bond[20,57,1], 
   bond[20,58,1], bond[20,59,1], 
   bond[21,60,1], bond[21,61,1], 
   bond[22,62,1], bond[22,63,1], 
   bond[23,64,1], bond[24,65,1], 
   bond[24,66,1], bond[25,67,1], 
   bond[25,68,1], bond[25,69,1], 
   bond[26,70,1], bond[26,71,1], 
   bond[27,72,1], bond[27,73,1], 
   bond[28,74,1], bond[29,75,1], 
   bond[29,76,1], bond[29,77,1], 
   bond[30,78,1], bond[30,79,1], 
   bond[30,80,1], bond[31,81,1]
     ]
  ).


% For easier reading let us convert molecules so that AtNr becomes the
% usual chemical symbol spelled as a lower-case constant (e.g. 1 -> H -> h).
% The number-to-symbol-mapping function nosymb is in/accesses the ELEMENTS KB:
% http://www.dfki.uni-kl.de/~vega/relfun+/elements.rfp
% http://www.dfki.uni-kl.de/~vega/relfun+/elements.rfp.html

conv-atom-list([]) :& [].
conv-atom-list([atom[Label,AtNr]|MoreAtoms]) :- AtSy .= nosymb(AtNr) &
   tup(atom[Label,AtSy]|conv-atom-list(MoreAtoms)).



% When browsing the *.html version, readers may now see a dialog script ...
% http://www.dfki.uni-kl.de/~vega/relfun+/nutrimine.script.html

% ... or conduct a semi-automatic dialog by using this CGI script:
% http://serv-302.dfki.uni-kl.de:8000/~ueben/cgi-bin/rfi

% Prior to CGI click, copy this line (without "%") and paste into Query window:
% exec "/home/boley/relfun/nutrimine/nutrimine.unpacked/nutrimine1"

% Then paste the following Result line before the first Query, changing 1 to 2:
% consult "/home/boley/relfun/nutrimine/nutrimine.rfp"
% exec "/home/boley/relfun/nutrimine/nutrimine.unpacked/nutrimine2"

% Now change 2 to 3 through 6, or "%"-passivate exec and pose your own queries:
% consult "/home/boley/relfun/nutrimine/nutrimine.rfp"
% %exec "/home/boley/relfun/nutrimine/nutrimine.unpacked/nutrimine2"
% tupof(tup(Food,nutrifood(vitamin-e,Food)))