%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% KNOWLEDGEBASE FOR THE BIOFUSION PROTOTYPE %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Version of: 10/2/2004 %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Author: Rupert Summerton %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% File name: biofusion.pl %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% Note: %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% All atoms/schema variables in queries that %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% originate DIRECTLY from the Fusion Proto- %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% type must be elements of a LIST. This is %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% because the Java code should be %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% application independent, and so it has %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% no way of knowing if a given goal %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% requires only one atom or variable, or %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% whether it requires many. %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% Clauses for functions %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(1) Disjunction. %disjunction(Disjuncts,Disjunction) :- Disjunction is a string formed from the disjunction of all the %terms in the list Disjuncts. For example: disjunction([[rain,snow],Disjunction). % ?- Disjunction = rain or snow disjunction(Disjuncts,Disjunction) :- removeduplicates(Disjuncts,[],DisjunctsWODuplicates), converttochars(DisjunctsWODuplicates,CharsLists), removefirstlist(CharsLists,EditedLists,FirstList), builddisjunction(EditedLists,FirstList,DisjunctionList), atom_chars(Disjunction,DisjunctionList). %converttochars(Terms,CharsLists) :- CharsLists is a list of lists. The lists are lists of chars that %correspond to the Terms in the list Terms. converttochars([Term|Rest1],[Chars|Rest2]) :- atom_chars(Term,Chars), converttochars(Rest1,Rest2). converttochars([],[]). %removefirstlist(CharsLists,EditedLists,FirstList) :- EditedLists is the list of lists CharsLists, but %with the first list removed, as FirstList. The purpose of this is simply to set up the data in a way that makes it %easier for predicate makedisjunction to create a string of the disjunction of all the terms with the most votes. removefirstlist([H|T],T,H). %buildisjunction(CharsLists,CurrentList,DisjunctionList) :- DisjunctionList is a list of ASCII codes corresponding %to the string which is the disjunction of all the terms in list CharsLists. For example, if the terms %in CharsLists were the ASCII codes corresponding to "rain","showers","snow", then DisjunctionList would be the list of ASCII codes %corresponding to the string "rain, showers or snow". CurrentList is an accumulator. %[44,32] are the ASCII codes for ", " builddisjunction([H|T],CurrentList,DisjunctionList) :- T \== [], append(CurrentList,[44,32],X), append(X,H,Y), builddisjunction(T,Y,DisjunctionList). %[32,111,114,32] are the ASCII codes for " or " builddisjunction([H],CurrentList,DisjunctionList) :- append(CurrentList,[32,111,114,32],X), append(X,H,DisjunctionList). %We need this for the case where the original list has only one member. builddisjunction([],DisjunctionList,DisjunctionList). %(2) Conjunction. %conjunction(Conjuncts,Conjunction) :- Conjunction is a string formed from the conjunction of all the %terms in the list Conjuncts. For example: conjunction([[rain,snow],Conjunction). % ?- Conjunction = rain and snow conjunction(Conjuncts,Conjunction) :- removeduplicates(Conjuncts,[],ConjunctsWODuplicates), converttochars(ConjunctsWODuplicates,CharsLists), removefirstlist(CharsLists,EditedLists,FirstList), buildconjunction(EditedLists,FirstList,ConjunctionList), atom_chars(Conjunction,ConjunctionList). %buildconjunction(CharsLists,CurrentList,ConjunctionList) :- ConjunctionList is a list of ASCII codes corresponding %to the string which is the conjunction of all the terms in list CharsLists. For example, if the terms %in CharsLists were the ASCII codes corresponding to "rain","showers","snow", then ConjunctionList would be the list of ASCII codes %corresponding to the string "rain, showers and snow". CurrentList is an accumulator. %[44,32] are the ASCII codes for ", " buildconjunction([H|T],CurrentList,ConjunctionList) :- T \== [], append(CurrentList,[44,32],X), append(X,H,Y), buildconjunction(T,Y,ConjunctionList). %[32,97,110,100,32] are the ASCII codes for " or " buildconjunction([H],CurrentList,ConjunctionList) :- append(CurrentList,[32,97,110,100,32],X), append(X,H,ConjunctionList). %We need this for the case where the original list has only one member. buildconjunction([],ConjunctionList,ConjunctionList). %removeduplicates(List,Accumulator,ListWithoutDupes) :- ListWithoutDupes is the list List, with all duplicates removed. %Accumulator should be the empty list when this predicate is called. %For example: removeduplicates([a,b,c,b,b,d,b,e],[],X). % ?- X = [a,b,c,d,e] %Case 1: Aleady in list, so don't add. removeduplicates([H|T],Accumulator,ListWODupes) :- member(H,Accumulator), removeduplicates(T,Accumulator,ListWODupes). %Case 2: Not in list, so add. removeduplicates([H|T],Accumulator,ListWODupes) :- not member(H,Accumulator), append(Accumulator,[H],NewList), removeduplicates(T,NewList,ListWODupes). removeduplicates([],ListWODupes,ListWODupes). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Proteins in knowledge base %CATH Superfamily: 3.30.559.10 allowedprotein('1nocB0'). allowedprotein('1dpb00'). allowedprotein('1dpc00'). allowedprotein('1dpd00'). allowedprotein('1eaa00'). allowedprotein('1eab00'). allowedprotein('1eac00'). allowedprotein('1ead00'). allowedprotein('1eae00'). allowedprotein('1eaf00'). allowedprotein('1c4tA0'). allowedprotein('1c4tB0'). allowedprotein('1c4tC0'). allowedprotein('1e2o00'). allowedprotein('1cia00'). allowedprotein('1cla00'). allowedprotein('1qca00'). allowedprotein('2cla00'). allowedprotein('3cla00'). allowedprotein('4cla00'). %CATH Superfamily: 3.40.50.1900 allowedprotein('1qoqB2'). allowedprotein('1a5aB2'). allowedprotein('1beuB2'). allowedprotein('1ubsB2'). allowedprotein('2tysB2'). allowedprotein('1a5bB2'). allowedprotein('1ttqB2'). allowedprotein('2trsB2'). allowedprotein('1bksB2'). allowedprotein('1fuyB2'). allowedprotein('1a50B2'). allowedprotein('1ttpB2'). allowedprotein('2tsyB2'). allowedprotein('1wsyB2'). allowedprotein('1cw2B2'). allowedprotein('1c8vB2'). allowedprotein('1a5sB2'). allowedprotein('1c29B2'). allowedprotein('1c9dB2'). allowedprotein('1cx9B2'). allowedprotein('2wsyB2'). allowedprotein('1qopB2'). allowedprotein('1tdj01'). allowedprotein('1oasA1'). allowedprotein('1oasB1'). allowedprotein('1d6sA1'). allowedprotein('1d6sB1'). allowedprotein('1fcjA1'). allowedprotein('1fcjD1'). allowedprotein('1fcjB1'). allowedprotein('1fcjC1'). allowedprotein('1jbqA1'). allowedprotein('1jbqB1'). allowedprotein('1jbqC1'). allowedprotein('1jbqD1'). allowedprotein('1jbqE1'). allowedprotein('1jbqF1'). allowedprotein('1f2dA1'). allowedprotein('1f2dB1'). allowedprotein('1f2dC1'). allowedprotein('1f2dD1'). recognizedprotein([H|T]) :- allowedprotein(H), recognizedprotein(T). recognizedprotein([]). %Terms in the heirarchy are the GO ID numbers. Some Fusion Rules %will need to output the name of the GO term as well. %functionalannotation(GOID,NameAndID) :- NameAndID is the name and ID corresponding to the GOID number. %These are all in the molecular_function hierarchy. functionalannotation('GO:0003673','Gene_Ontology (GO:0003673)'). functionalannotation('GO:0003674','molecular_function (GO:0003674)'). functionalannotation('GO:0003824','catalytic activity (GO:0003824)'). functionalannotation('GO:0016491','oxidoreductase activity (GO:0016491)'). functionalannotation('GO:0016705','oxidoreductase activity, acting on paired donors, with incorporation or reduction of molecular oxygen (GO:0016705)'). functionalannotation('GO:0016709','oxidoreductase activity, acting on paired donors, with incorporation or reduction of molecular oxygen, NAD or NADH as one donor, and incorporation of one atom of oxygen (GO:0016709)'). functionalannotation('GO:0004517','nitric oxide synthase activity (GO:0004517)'). functionalannotation('GO:0016740','transferase activity (GO:0016740)'). functionalannotation('GO:0016746','transferase activity, transferring acyl groups (GO:0016746)'). functionalannotation('GO:0016747','transferase activity, transferring groups other than amino-acyl groups (GO:0016747)'). functionalannotation('GO:0008415','acyltransferase activity (GO:0008415)'). functionalannotation('GO:0016417','S-acyltransferase activity (GO:0016417)'). functionalannotation('GO:0030523','dihydrolipoamide S-acyltransferase activity (GO:0030523)'). functionalannotation('GO:0008374','O-acyltransferase activity (GO:0008374)'). functionalannotation('GO:0016407','acetyltransferase activity (GO:0016407)'). functionalannotation('GO:0016413','O-acetyltransferase activity (GO:0016413)'). functionalannotation('GO:0008811','chloramphenicol O-acetyltransferase activity (GO:0008811)'). functionalannotation('GO:0016748','succinyltransferase activity (GO:0016748)'). functionalannotation('GO:0016751','S-succinyltransferase activity (GO:0016751)'). functionalannotation('GO:0004149','dihydrolipoamide S-succinyltransferase activity (GO:0004149)'). %%%%%%%%%%%%%%%%%%%% functionalannotation('GO:0016829','lyase activity (GO:0016829)'). functionalannotation('GO:0016835','carbon-oxygen lyase activity (GO:0016835)'). functionalannotation('GO:0016836','hydro-lyase activity (GO:0016836)'). functionalannotation('GO:0004122','cystathione beta-synthase activity (GO:0004122)'). functionalannotation('GO:0016839','other carbon-oxygen lyase activity (GO:0016839)'). functionalannotation('GO:0004124','cysteine synthase activity (GO:0004124)'). functionalannotation('GO:0004794','threonine dehydratase activity (GO:0004794)'). functionalannotation('GO:0004834','tryptophan synthase activity (GO:0004834)'). %These are in the cellular_component hierarchy. functionalannotation('GO:0005575','cellular_component (GO:0005575)'). functionalannotation('GO:0005623','cell (GO:0005623)'). functionalannotation('GO:0005622','intracellular (GO:0005622)'). functionalannotation('GO:0005737','cytoplasm (GO:0005737)'). %...But we overload this predicate, because sometimes we merely want the description, not the GO number. functionalannotation(['GO:0003673'],'Gene_Ontology', '(GO:0003673)'). functionalannotation(['GO:0003674'],'molecular_function', '(GO:0003674)'). functionalannotation(['GO:0003824'],'catalytic activity', '(GO:0003824)'). functionalannotation(['GO:0016491'],'oxidoreductase activity', '(GO:0016491)'). functionalannotation(['GO:0016705'],'oxidoreductase activity, acting on paired donors, with incorporation or reduction of molecular oxygen', '(GO:0016705)'). functionalannotation(['GO:0016709'],'oxidoreductase activity, acting on paired donors, with incorporation or reduction of molecular oxygen, NAD or NADH as one donor, and incorporation of one atom of oxygen', '(GO:0016709)'). functionalannotation(['GO:0004517'],'nitric oxide synthase activity', '(GO:0004517)'). functionalannotation(['GO:0016740'],'transferase activity', '(GO:0016740)'). functionalannotation(['GO:0016746'],'transferase activity, transferring acyl groups', '(GO:0016746)'). functionalannotation(['GO:0016747'],'transferase activity, transferring groups other than amino-acyl groups', '(GO:0016747)'). functionalannotation(['GO:0008415'],'acyltransferase activity', '(GO:0008415)'). functionalannotation(['GO:0016417'],'S-acyltransferase activity', '(GO:0016417)'). functionalannotation(['GO:0030523'],'dihydrolipoamide S-acyltransferase activity', '(GO:0030523)'). functionalannotation(['GO:0008374'],'O-acyltransferase activity', '(GO:0008374)'). functionalannotation(['GO:0016407'],'acetyltransferase activity', '(GO:0016407)'). functionalannotation(['GO:0016413'],'O-acetyltransferase activity', '(GO:0016413)'). functionalannotation(['GO:0008811'],'chloramphenicol O-acetyltransferase activity', '(GO:0008811)'). functionalannotation(['GO:0016748'],'succinyltransferase activity', '(GO:0016748)'). functionalannotation(['GO:0016751'],'S-succinyltransferase activity', '(GO:0016751)'). functionalannotation(['GO:0004149'],'dihydrolipoamide S-succinyltransferase activity', '(GO:0004149)'). functionalannotation(['GO:0016829'],'lyase activity', '(GO:0016829)'). functionalannotation(['GO:0016835'],'carbon-oxygen lyase activity', '(GO:0016835)'). functionalannotation(['GO:0016836'],'hydro-lyase activity','(GO:0016836)'). functionalannotation(['GO:0004122'],'cystathione beta-synthase activity', '(GO:0004122)'). functionalannotation(['GO:0016839'],'other carbon-oxygen lyase activity', '(GO:0016839)'). functionalannotation(['GO:0004124'],'cysteine synthase activity', '(GO:0004124)'). functionalannotation(['GO:0004794'],'threonine dehydratase activity', '(GO:0004794)'). functionalannotation(['GO:0004834'],'tryptophan synthase activity', '(GO:0004834)'). %These are in the cellular_component hierarchy. functionalannotation(['GO:0005575'],'cellular_component', '(GO:0005575)'). functionalannotation(['GO:0005623'],'cell', '(GO:0005623)'). functionalannotation(['GO:0005622'],'intracellular', '(GO:0005622)'). functionalannotation(['GO:0005737'],'cytoplasm', '(GO:0005737)'). %getannotations(GOIDs,Annotations) :- Annotations is a list of the functional annotations for the GO numbers in GOIDs getannotations([H1|T1],[Annotation|T2]) :- functionalannotation(H1,Annotation), getannotations(T1,T2). getannotations([],[]). %If the functional annotation on which all proteins agree is sufficiently general, %i.e. it's high up the hierarchy, then it's too gneral to be informative. This suggests %that the proteins that were selected do not belong to any natural grouping, and so %should not be merged. requiredspecificity/1 takes a GO id number as argument %and succeeds if this GO term is sufficiently specific to be informative. %requiredspecificity(GOID) :- GOID is the id number of a GO term that is deemed to be sufficiently specific % such that proteins sharing that level of functionality can be meaningfully grouped together. requiredspecificity('GO:0003824'). requiredspecificity('GO:0016491'). requiredspecificity('GO:0016705'). requiredspecificity('GO:0016709'). requiredspecificity('GO:0004517'). requiredspecificity('GO:0016740'). requiredspecificity('GO:0016746'). requiredspecificity('GO:0016747'). requiredspecificity('GO:0008415'). requiredspecificity('GO:0016417'). requiredspecificity('GO:0030523'). requiredspecificity('GO:0008374'). requiredspecificity('GO:0016407'). requiredspecificity('GO:0016413'). requiredspecificity('GO:0008811'). requiredspecificity('GO:0016748'). requiredspecificity('GO:0016751'). requiredspecificity('GO:0004149'). %Checks a list of GO #s to see if they are all of the required specificity. arerequiredspecificity([H|T]) :- requiredspecificity(H), arerequiredspecificity(T). arerequiredspecificity([]). %Conversely, if the functionality is too general to be informative, we want to warn the user. %notrequiredspecificity(GOID, Warning) :- GOID is id number of a GO term that is too general to be informative. % proteins whose functional annotations agree only at this level do % not belong to any menaingfull grouping. Warning is a message informing the user of this. %Note that this predicate is NOT the negation of requiredspecificity since if the GOID is not recognized both predicates will fail. notrequiredspecificity('GO:0003673','Functional annotations are too general to be informative. These proteins do not belong to any meaningfull grouping.'). notrequiredspecificity('GO:0003674','Functional annotations are too general to be informative. These proteins do not belong to any meaningfull grouping.'). %Checks a list of GO #s to see if they are all not of the required specificity. %So note that this predicate is not the negation of arerequiredspecificity. Note also %that we are assuming here that if there is more than one least upper bound (i.e if input %terms shar more than one parent), then those upper bound will all be at the same depth--and so %if one is too general, then all will be too general. arenotrequiredspecificity([H|T],Warning) :- notrequiredspecificity(H,Warning), arenotrequiredspecificity(T,Warning). arenotrequiredspecificity([],Warning). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%% Code for least upper bound %%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %leastupperbound(TextEntries,FirstCommonAncestor) :- TextEntries is a list of text entries that ought to be %part of a tree hierarchy. FirstCommonAncestor is the member of that hierarchy that is the ancestor of all the %text entries in TextEntries that has the greatest depth, or least height, in the tree. %All entries in text entries belong to the same semantic net. leastupperbound(TextEntries,FirstCommonAncestor) :- aremembers(TextEntries), getlineages(TextEntries,Lineages), sameroot(Lineages), getleastupperbound(Lineages,FirstCommonAncestor). %All entries in text entries do not belong to the same semantic net. leastupperbound(TextEntries,'No least upper bound') :- getlineages(TextEntries,Lineages), not sameroot(Lineages). %getlineages(TextEntries,Lineages) :- Lineages is a list of all the lineages of the members of TextEntries. %Lineages is thus a list of lists. %For example: ?- getlineages([andy,jack,fred],X). % X = [[tom,bob],[tom,bob,jim],[tom,bob,jim,jane]] %The lineages are reversed so that the root memeber (in this case tom) comes first. getlineages([H|T1],[ReversedLineage|T2]) :- lineage(H,Lineage), reverse(Lineage,ReversedLineage), getlineages(T1,T2). getlineages([],[]). %lineage(Person,Lineage) :- Lineage is a list of the ancestors of Person. %For example: ?- lineage(jane,X). % X = [jane,jim,bob,tom] %This rule makes sure person herself is included in lineage. If this isn't done, rule %getleastupperbound will not give the parent as answer to a parent child pair, but instead, %will return the parent of the parent. (i.e. without this rule, leastupperbound([fred,jane],X) %would return jim, when it should return jane.) %We also want to check first to make sure that Person is a member of the hierarchy. lineage(Person,[Person|Rest]) :- auxlineage(Person,Rest). auxlineage(Person,[X|Rest]) :- parent(X,Person), auxlineage(X,Rest),!. auxlineage(Person,[]). %aremembers(TextEntries) :- succeeds if all text entries in list TextEntries are members of some or other semantic net. aremembers([H|T]) :- ismember(H), length(T,L), L > 0, aremembers(T). aremembers([H]) :- ismember(H). %ismember(X) :- succeeds if X is member of the semantic net/hierachy--i.e if X is a relata of Parent. ismember(X) :- parent(X,Y) ; parent(Y,X). parent(john,bob). parent(bob,sam). parent(sam,fred). parent(john,bill). parent(bill,mary). parent(bill,sally). parent(bill,ivor). parent(mary,dave). parent(sally,susan). %no unique lub parent(sally,peter). parent(ivor,peter). parent(ivor,susan). parent(dave,steve). parent(dave,mark). parent(peter,mark). parent(mark,brian). parent(susan,mike). %parent(Parent,Child). %tree hierarchy for functional annotations of proteins from GO database. %First two nodes are common to functional annotations parent('GO:0003673','GO:0003674'). parent('GO:0003674','GO:0003824'). %Leaf is 0030523 parent('GO:0003824','GO:0016740'). parent('GO:0016740','GO:0016746'). parent('GO:0016746','GO:0016747'). parent('GO:0016747','GO:0008415'). parent('GO:0008415','GO:0016417'). parent('GO:0016417','GO:0030523'). %Leaf is 0004517 parent('GO:0003824','GO:0016491'). parent('GO:0016491','GO:0016705'). parent('GO:0016705','GO:0016709'). parent('GO:0016709','GO:0004517'). %Leaf is 0008811 parent('GO:0008415','GO:0008374'). parent('GO:0008415','GO:0016407'). parent('GO:0008374','GO:0016413'). parent('GO:0016407','GO:0016413'). %Note: this violates tree structure. parent('GO:0016413','GO:0008811'). %Leaf is 0004149 parent('GO:0008415','GO:0016748'). parent('GO:0016417','GO:0016751'). parent('GO:0016748','GO:0016751'). %Note: this violates tree structure. parent('GO:0016751','GO:0004149'). %For new case study. parent('GO:0003824','GO:0016829'). parent('GO:0016829','GO:0016835'). parent('GO:0016835','GO:0016836'). parent('GO:0016836','GO:0004122'). parent('GO:0016835','GO:0016839'). parent('GO:0016839','GO:0004124'). parent('GO:0016836','GO:0004794'). parent('GO:0016836','GO:0004834'). %These are in the cellular_component hierarchy. parent('GO:0005575','GO:0005623'). parent('GO:0005623','GO:0005622'). parent('GO:0005622','GO:0005737'). %sameroot(Lineages) :- succeeds if all lineages in list Lineages share a root. If this test fails, we do not want %to return a least upper bound. sameroot(Lineages) :- getheads(Lineages,Heads), testheads(Heads). %getleastupperbound(Lineages,FirstCommonAncestor) :- FirstCommonAncestor is the first or 'most recent' member common %to all lineages in Lineages. For example: % ?- getleastupperbound([[bob,tom],[jim,bob,tom],[jane,jim,bob,tom]],FirstCommonAncestor). % FirstCommonAncestor = bob %The basic strategy used is to start at the ROOT of the lineages and work down (or back) until we no longer %have a member common to all; the previous member is then the FirstCommonAncestor. getleastupperbound(Lineages,FirstCommonAncestor) :- findleastupperbound(Lineages,Lineages,FirstCommonAncestor). %The recursive case: all heads of lineages are the same, and there is more than one member in the lineage. findleastupperbound(Lineages,PrevLineages,FirstCommonAncestor) :- notsingletonlists(Lineages), getheads(Lineages,Heads), testheads(Heads), stripheads(Lineages,Tails), findleastupperbound(Tails,Lineages,FirstCommonAncestor). %One case in which we've found the first common ancestor. At least one lineage is down to a single member, so %given that the heads of the lineages are the same, this is the first common ancestor. %This case occurs when the lineages are NOT of the same length. %For example, if the ORIGINAL lineages are: % [tom,bob] % [tom,bob,jim] % [tom,bob,jim,jane] %then this rule will capture the FirstCommonAncestor. findleastupperbound(Lineages,PrevLineages,FirstCommonAncestor) :- not notsingletonlists(Lineages), getheads(Lineages,Heads), testheads(Heads), gethead(Heads,FirstCommonAncestor). %This is the second kind of case in which we find the FirstCommonAncestor. Here the lineages are equal %in length. For example, if the ORIGINAL lineages are: % [tom,pat,sally,olly] % [tom,bob,jim,jane] % [tom,pat,sally,luke] % [tom,bob,jim,jane] %then this rule will capture the FirstCommonAncestor. findleastupperbound(Lineages,PrevLineages,FirstCommonAncestor) :- getheads(Lineages,Heads), not testheads(Heads), getheads(PrevLineages,PrevHeads), gethead(PrevHeads,FirstCommonAncestor). %getheads(Lineages,Heads) :- Lineages is a list of lineages of the textentries whose least upper bound we are searching for. %Lineages is thus a list of lists. Heads is a list of the heads of each of those lists in Lineages. getheads([[H|T1]|T2],[H|T3]) :- getheads(T2,T3). getheads([],[]). %gethead(Heads,Head) :- Head is simply the head of list Heads. gethead([H|T],H). %testheads(Heads) :- Heads is a list of the heads of all the lists in Lineages. Succeeds if all heads are the same. testheads([H1,H2|T]) :- H1 == H2, testheads([H2|T]). testheads([H|[]]). %stripheads(Lineages,Tails) :- Tails is the list of lists in Lineages, but with the head of each list removed. stripheads([[H|T1]|T2],[T1|T3]) :- stripheads(T2,T3). stripheads([],[]). %notsingletonlists(Lineages) :- succeeds if all the lists in lineages are not singletons, i.e. their length is greater than 1. notsingletonlists([List|T]) :- length(List,Length), Length > 1, notsingletonlists(T). notsingletonlists([]). %reverselineages(Lineages,ReverseLineages) :- ReverseLineages is the list of lineages in Lineages, but with the %members of each LINEAGE LIST reversed. (Code not used at present.) reverselineages([Lineage|T1],[ReversedLineage|T2]) :- reverse(Lineage,ReversedLineage), reverselineages(T1,T2). reverselineages([],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Code for extracting key words. %getkeywords(Ancestors,Keywords) :- Ancestors is a list of GOID #s of the ancestors of the LeastUpperBound, %the functional annotation from the GO hierarchy that is %the least general term that is general enough to cover the functions of all the proteins to be merged. (i.e. this %is the output of the predicate leastupperbound.) Keywords is a list of all the keywords or phrases that occur in the %functional annotations of the ancestors. %e.g. | ?- getkeywords(['GO:0003673','GO:0003674','GO:0003824','GO:0016740','GO:0016746'],Keywords). % Keywords = [' transferring acyl groups','Gene_Ontology','catalytic activity',molecular_function,'transferase activity'] getkeywords(Ancestors,Keywords) :- getfunctionalannotations(Ancestors,FunctionalAnnotations), splitfunctionalannotations(FunctionalAnnotations,SplitFunctionalAnnotations), flatten(SplitFunctionalAnnotations,FlattenedList), sort(FlattenedList,Keywords). %gets functional annotations of all ancestors of least upper bound. %getfunctionalannotations(Ancestors,FunctionalAnnotations) :- Ancestors is a list of the GOID #s that are %ancestors of the least upper bound. FunctionaAnnotations is a list of the annotations for each of those terms. getfunctionalannotations([GOID|T1],[FA|T2]) :- getfunctionalannotation(GOID,FA), getfunctionalannotations(T1,T2). getfunctionalannotations([],[]). %getfunctionalannotation(GOID,FunctionalAnnotation) :- FunctionalAnnotation is the functional annotation for the GO term with ID# GOID. getfunctionalannotation(GOID,FunctionalAnnotation) :- functionalannotation([GOID],FunctionalAnnotation,GOIDNum). %Splits functional annotations for all ancestors of least upper bound. %splitfunctionalannotations(FunctionalAnnotations,SplitFunctionalAnnotations) :- FunctionalAnnotations is a list of functional %annotatons. SplitFunctionalAnnotations is a list of lists, where each list is a list of the key words/phrases in each annotation. splitfunctionalannotations([H1|T1],[FA|T2]) :- splitfunctionalannotation(H1,FA), splitfunctionalannotations(T1,T2). splitfunctionalannotations([],[]). %splitfunctionalannotation(FunctionalAnnotation,List) :- List is a list of the keywords or phrases in the atom FunctionalAnnotation. %In the GO hierarchy, these annotations are segmented into key words or phrases using commas, so we split the atom up at the commas. splitfunctionalannotation(FunctionalAnnotation,ListOfAtoms) :- atom_chars(FunctionalAnnotation,Chars1), auxsplitfunctionalannotation(Chars1,ListsOfChars), converttoatoms(ListsOfChars,ListOfAtoms). %44 is ASCII for comma, ",". auxsplitfunctionalannotation(Chars1,[Chars2|T]) :- Chars1 \= [], getsubstring(Chars1,44,1,Chars2,Chars3), auxsplitfunctionalannotation(Chars3,T). auxsplitfunctionalannotation([],[]). %getsubstring(Chars1,Char,Flag1,Flag2,Chars2) :- Chars2 is a list of ASCII codes corresponding to the %list in Chars1 up to but not including the first occurrence of the ASCII code Char. %Chars3 is a list of the remaining chars in Chars1 except for Char. (i.e. Chars1 = Chars2 + Char + Chars3) %Flag indicates if the ASCIIcode Char has been encountered. 1 means the code has not yet been %encountered, so numbers in Chars1 should be added to Chars2; 0 means it has been encountered, %so numbers should be added to Chars3. If Flag is 0, subsequent occurrences of Char should be added to Chars3. %We have a match with first occuurence of Char, so set Flag to 0. Don't add to anything. getsubstring([Char|T],Char,X,Chars2,Chars3) :- X =:= 1, getsubstring(T,Char,0,Chars2,Chars3). %We have a match with a subsequent occurrence of Char. So add char to Chars3. getsubstring([Char|T],Char,X,Chars2,[Char|T2]) :- X =:= 0, getsubstring(T,Char,0,Chars2,T2). %Flag is 0, so don't add to Chars2, add to Chars3. getsubstring([H|T1],Char,X,Chars2,[H|T2]) :- X =:= 0, Char =\= H, getsubstring(T1,Char,0,Chars2,T2). %Flag is 1, so add to Chars2, not to Chars3. getsubstring([H|T1],Char,X,[H|T2],Chars3) :- X =:= 1, Char =\= H, getsubstring(T1,Char,1,T2,Chars3). %Base case getsubstring([],Char,X,[],[]). %Converts the list of lists of chars back to a list of atoms. converttoatoms([H1|T1],[Atom|T2]) :- atom_chars(Atom,H1), converttoatoms(T1,T2). converttoatoms([],[]). %flatten(List,FlattenedList) :- FlattenedList is a list of the elements in List. flatten(Xs,Ys) :- flatten(Xs,[],Ys). flatten([X|Xs],S,Ys) :- list(X), flatten(X,[Xs|S],Ys). flatten([X|Xs],S,[X|Ys]) :- constant(X), X \= [], flatten(Xs,S,Ys). flatten([],[X|S],Ys) :- flatten(X,S,Ys). flatten([],[],[]). %We also need to find the ancestors of the node or nodes which are the least upper bound. Predicate ancestors/2 which is defined %as a helper predicate for semanticgeneralization/2 does exactly this, for each node. %findancestors(Nodes,Ancestors) :- Ancestors is a list of the set of all the ancestors of nodes in Nodes. findancestors(Nodes,Ancestors) :- findallancestors(Nodes,ListOfLists), flatten(ListOfLists,FlattenedList), sort(FlattenedList,Ancestors). findallancestors([Node|T1],[Ancestors|T2]) :- ancestors(Node,Ancestors), findallancestors(T1,T2). findallancestors([],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Code for semantic generalization. This does the same as the code for finding the least upper bound, except %that instead of assuming the terms that are hierarchically related form a tree, the data structure on which %this predicate works is a directed acyclic graph, since this corresponds to the hierarchical classification %of functional annotations found in GO. Note that because the data structure is a tree, it is possible that %the input terms whose least upper bound is being sort share more than one parent. If so, in such cases we %consider there to be more than one least upper bound, and this predicate returns their conjunction. %Top level predicate-this is the predicate that occurs as a condition in the fusion rules. %semanticgeneralization(Nodes,SortedLUBs) :- SortedLUBs is the least upper bound (or bounds) for the nodes in Nodes. semanticgeneralization(Nodes,SortedLUBs) :- ancestorsfornodes(Nodes,Ancestors), intersection(Ancestors,Intersection), getdepths(Intersection,Depths), getmaxdepth(Depths,MaxPair), checkties(MaxPair,Depths,Ties), %New getgoterms(Ties,LUBs), sort(LUBs,SortedLUBs). %getterm(MaxPair,LUB). %ancestorsfornodes(Nodes,Ancestors) :- Ancestors is a list of lists, where each list is a list of the ancestors %of each node in nodes. ancestorsfornodes([Node|T1],[Ancestors|T2]) :- ancestors(Node,Ancestors), ancestorsfornodes(T1,T2). ancestorsfornodes([],[]). %ancestors(Node,Ancestors) :- Ancestors is a list of the ancestors of node Node in a graph. ancestors(Node,Ancestors) :- getancestors([Node],[],Ancestors). getancestors([H|T],NodesChecked,Ancestors) :- parents(H,Parents), union(Parents,T,T2), getancestors(T2,[H|NodesChecked],Ancestors). getancestors([],Ancestors,Ancestors). %parents(Node,Parents) :- Parents is a list of the parents (i.e. immediate ancestors) of Node--remember we're dealing with %graph here, not a tree, so a node can have more than one parent. parents(Node,Parents) :- bagof(OtherNode, parent(OtherNode,Node),Parents),!. parents(Node,[]). union([X|T],Y,Z) :- member(X,Y), union(T,Y,Z). union([X|T],Y,[X|Z]) :- not member(X,Y), union(T,Y,Z). union([],Y,Y). %%%%%%%%%%%%%%%%%%%%% %Need to find intersection of all ancestors. (Once we have the intersection, %we can figure out which has greatest depth--that's the least upper bound.) %intersection(ListOfLists,Intersection) :- Intersection is a list of all elements that occur in all of the lists in ListOfLists. intersection([List|Rest],Intersection) :- intersection(List,Rest,Intersection). %Strategy is to take the first list in our list of lists; for each member in that list %check if it's a member of each of the other lists, and if it is, add it to list Intersection. %Element (from first list) is in all other lists, so add to intersection. intersection([Element|T1],Rest,[Element|T2]) :- memberofalllists(Element,Rest), intersection(T1,Rest,T2). %Element (from first list) is not in all other lists, so don't add to intersection. intersection([Element|T1],Rest,Intersection) :- not memberofalllists(Element,Rest), intersection(T1,Rest,Intersection). %Base case. intersection([],Rest,[]). %memberofalllists(Element,ListOfLists) :- succeeds if Element is member of all lists in ListOfLists. memberofalllists(Element,[List|Rest]) :- member(Element,List), memberofalllists(Element,Rest). memberofalllists(Element,[]). %%%%%%%%%%%%%%%%%%%%%%%% %getmaxdepth(Depths,Max) :- Max is the node/depth pair with the greatest depth. getmaxdepth([X|Xs],Max) :- getmaxdepth(Xs,X,Max). getmaxdepth([[Term1,Num1]|Xs],[Term2,Num2],Max) :- Num1 =< Num2, getmaxdepth(Xs,[Term2,Num2],Max). getmaxdepth([[Term1,Num1]|Xs],[Term2,Num2],Max) :- Num1 > Num2, getmaxdepth(Xs,[Term1,Num1],Max). getmaxdepth([],Max,Max). %getterm(WinningPair,Term) :- Term is the term component of WinningPair. getterm([Term,Depth],Term). %getdepths(Nodes,Depths) :- Depths is a list of the depths of the nodes in Nodes, in the form of node\depth pairs. getdepths([H1|T1],[[H1,Depth]|T2]) :- depth(H1,List,0,Depth), getdepths(T1,T2). getdepths([],[]). %depth(Node,Depth) :- Depth is the depth of node Node in the GO hierarchy. Note: we assume %that even though the hierarchy is not a tree but a graph, that nevertheless the parents of any node are %all at the same depth. Otherwise, the idea of depth (and so the idea of a least upper bound) has no place %in this hierarchy. depth(Node,[Parent|Rest],Start,Depth) :- parent(Parent,Node), D is Start + 1, depth(Parent,Rest,D,Depth),!. depth(Root,[],Depth,Depth). %getgoterms(Pairs,GOTerms) :- GOTerms is a list of the GO id #s from the list Pairs, %which is a list of GO id#s/depth pairs. getgoterms([[Term,Depth]|T1],[Term|T2]) :- getgoterms(T1,T2). getgoterms([],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %These are helper clauses used to determine if there is more than one least upper bound %(this might arise because two or mor annotations in the GO hierarchy share more than one parent.) %checkties(WinningPair,VoteList,TiesForMax) :- TiesForMax is a list of Term-depths pairs, where the terms are tied %for the greatest depths. An example: checkties([GO:0008811,2],[[GO:0004149,2],[GO:0003523,1]],TiesForMax). % ?- TiesForMax = [[GO:0008811,2],[GO:0004149,2]] %We have a tie with the maximum number of votes, so add to list. checkties([Term1,Num1],[[Term2,Num2]|Rest],[[Term2,Num2]|Rest2]) :- Num1 =:= Num2, checkties([Term1,Num1],Rest,Rest2). %We have less votes for this term, so don't add to list. checkties([Term1,Num1],[[Term2,Num2]|Rest],TiesForMax) :- Num1 > Num2, checkties([Term1,Num1],Rest,TiesForMax). %There shouldn't be a term that has more votes than the term in WinningPair--but just in case.. checkties([Term1,Num1],[[Term2,Num2]|Rest],[[Term2,Num2]]) :- Num2 > Num1, checkties([Term2,Num2],Rest,[]). checkties([Term1,Num1],[],[]). %constructconjunction(TiesForMax,Conjunction) :- Conjunction is a string formed from the conjunction of all the %terms in the list TiesForMax. For example: constructconjunction([[rain,2],[snow,2]],Conjunction). % ?- Conjunction = rain and snow constructconjunction(TiesForMax,Conjunction) :- converttochars(TiesForMax,CharsLists), removefirstlist(CharsLists,EditedLists,FirstList), makeconjunction(EditedLists,FirstList,ConjunctionList), atom_chars(Conjunction,ConjunctionList). %converttochars(TiesForMax,CharsLists) :- CharsLists is a list of lists. The lists are lists of chars that %correspond to the Terms in the list TiesForMax, i.e. the list of Terms, Votes for terms pairs. converttochars([[Term,Num]|Rest1],[Chars|Rest2]) :- atom_chars(Term,Chars), converttochars(Rest1,Rest2). converttochars([],[]). %removefirstlist(CharsLists,EditedLists,FirstList) :- EditedLists is the list of lists CharsLists, but %with the first list removed, as FirstList. The purpose of this is simply to set up the data in a way that makes it %easier for predicate makedisjunction to create a string of the disjunction of all the terms with the most votes. removefirstlist([H|T],T,H). %makeconjunction(CharsLists,CurrentList,ConjunctionList) :- ConjunctionList is a list of ASCII codes corresponding %to the string which is the conjunction of all the terms in list CharsLists. For example, if the terms %in CharsLists were the ASCII codes corresponding to "rain","showers","snow", then ConjunctionList would be the list of ASCII codes %corresponding to the string "rain and showers and snow". CurrentList is an accumulator. %[32,97,110,100,32] are the ASCII codes for " and " makeconjunction([H|T],CurrentList,ConjunctionList) :- append(CurrentList,[32,97,110,100,32],X), append(X,H,Y), makeconjunction(T,Y,ConjunctionList). makeconjunction([],ConjunctionList,ConjunctionList). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% Overloaded code for semanticgeneralization. The reason %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% we wish to overload this predicate is that in some %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% cases we wish to find the genralization of a group of %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% protein domains some of which do NOT have GO ID nums. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% In these cases, we check to see if this protein has a %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% SEQUENCE SCORE > 60% with one of the other protein %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% domains being merged whose GO ID number is known. If %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% it does, then we know we can merge the whole set to %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% find the semantic generalization of protein domains %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% in the usual way without the result being affected. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /** %Top level predicate-this is the predicate that occurs as a condition in the fusion rules. %semanticgeneralization(Names,Nodes,LUB) :- LUB is the least upper bound for the nodes in Nodes. semanticgeneralization(Names,Nodes,SortedLUBs) :- assignidnumstonulls(Names,Nodes,NoNulls), ancestorsfornodes(NoNulls,Ancestors), intersection(Ancestors,Intersection), getdepths(Intersection,Depths), getmaxdepth(Depths,MaxPair), checkties(MaxPair,Depths,Ties), getgoterms(Ties,LUBs), sort(LUBs,SortedLUBs). %assignidnumstonulls(Names,Nodes,NoNulls) :- NoNulls is a list of GOID numbers with no nulls. Nodes is a list %of GOID numbers for all the protein domains in list Names. But some proteins may have no ID number, and so %Nodes itself may contain some "nulls". NoNulls is the same list of GOID numbers, but with any "nulls" replaced %with the GOID number of a protein domain with a sequence similarity score > 60% to the protein domain whose GOID %was not known. %Case 1: Node is not null, so do nothing. assignidnumstonulls([H1|T1],[GOID|T2],[GOID|T3]) :- assignidnumstonulls(T1,T2,T3). %Case 2: Node is null, so get GOID from protein with similar sequence. assignidnumstonulls([H1|T1],[null|T2],[GOID|T3]) :- findsimilarprotein(H1,Protein), getgoid(Protein,GOID), assignidnumstonulls(T1,T2,T3). %Base Case. assignidnumstonulls([],[],[]). %findsimilarprotein(Protein1,Protein2) :- Protein1 is the protein domain whose GOID is unknown. Protein2 %is a protein domain whose sequence similarity is greater than 60% to Protein1. findsimilarprotein(Protein1,Protein2) :- sequencescore(Protein1,Protein2,X,Y), X > 60. %sequencescore(Protein1,Protein2,SequenceScore,StructureScore) :- SequenceScore is a percentage simialrity %in sequence between the two proteins. sequencescore('1f2dC1','1f2dD1',100,98.27). %Facts correlating proteins and GOIDs getgoid('1f2dC1','GO:0016747'). %Better strategy. loop over Names and see if any protein there is similar seq. to null protein. If that's %true for ALL nulls, then go ahead and find lub as before, since we know result will be same even for proteins %whose GOID is unknown. **/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Top level predicate-this is the predicate that occurs as a condition in the fusion rules. %semanticgeneralization(Names,Nodes,SortedLUBs) :- SortedLUBs is the least upper bound or bounds for the nodes in Nodes. semanticgeneralization(Names,GOIDs,SortedLUBs) :- removeproteinswithoutids(Names,GOIDs,NamesWithGOIDs), checkproteinswithoutids(NamesWithGOIDs,Names,GOIDs), %must remove nulls from GOIDs stripnulls(GOIDs,GOIDsWithoutNulls), ancestorsfornodes(GOIDsWithoutNulls,Ancestors), intersection(Ancestors,Intersection), getdepths(Intersection,Depths), getmaxdepth(Depths,MaxPair), checkties(MaxPair,Depths,Ties), getgoterms(Ties,LUBs), sort(LUBs,SortedLUBs). %Note, if this clause fails because some input domains are NOT %similar in sequence to another input domain whose GOID IS known, % i.e. checkproteinswithoutids(NamesWithGOIDs,Names,GOIDs) fails, % then the rule fails, but a new rule, using the clause cannotfindsemanticgeneralization %will succeed. %stripnulls(List,ListWithoutNulls) :- List is a list of atoms (say terms for today's weather, or terms for temps, etc). %ListWithoutNulls is the same list, except any atoms which consist of the string "null" have been removed. This allows %subsequent predicates to check that the list of atoms are of similar magnitudes, or are similar terms, etc. Using this %predicate as a helper predicate for similartemps (etc.), and equivalentterms means that the predicate groundable is no %longer required, and so the fusion rules are simpler. %terms is null, so drop it. stripnulls([H1|T1],ListWithoutNulls) :- H1 == null, stripnulls(T1,ListWithoutNulls). %terms is not null, so keep it. stripnulls([H1|T1],[H1|T2]) :- not H1 == null, stripnulls(T1,T2). stripnulls([],[]). %removeproteinswithoutids(Names,GOIDs,NamesWithGOIDs) :- Names is a list of names of protein domains to be merged. %GOIDs is a list of their GOID numbers. But some of these numbers may be missing--i.e. the list contains a "null" instead. %NamesWithGOIDs is the subset of names in Names that have GOIDs. (We need this because in checking to see if those %proteins that don't have an ID number are similar in sequence to another protein, we need to make sure that the second %protein DOES have an ID number.) %Name has an ID, so add to our list of names with IDs. removeproteinswithoutids([Name|T1],[GOID|T2],[Name|T3]) :- not GOID == null, removeproteinswithoutids(T1,T2,T3). %Name has NO ID, so do NOT add to our list of names with IDs. removeproteinswithoutids([Name|T1],[null|T2],NamesWithGOIDs) :- removeproteinswithoutids(T1,T2,NamesWithGOIDs). %Base case. removeproteinswithoutids([],[],[]). %checkproteinswithoutids(NamesWithGOIDs,Names,GOIDs) :- Names is a list of names of proteins domains whose %GOIDs are given in list GOIDs. But some proteins have no GOID, and a null is entered in the list instead. %This predicate succeeds if evey protein in Names that has no ID has a sequence similarity of 60 or greater %to another protein in Names that has a GOID. NamesWithGOIDs is the subset of names of those protein domains %which DO have ID numbers. It would be of no use to know that a protein domain whose ID is not known was similar %to another protein whose ID was also not known, because that would not allow us to infer that the least upper bound %of the whole set of proteins is the same as the least upper bound of the subset of those proteins whose GOIDs ARE known. %Hence, we need this list, NamesWithGOIDs, to check to see if any protein domain in Names without an %ID number has a sequence score > 60 with one of the protein domains in this other list. %Case 1: Name has an ID, so do nothing. checkproteinswithoutids(NamesWithGOIDs,[Name|T1],[GOID|T2]) :- not GOID == null, checkproteinswithoutids(NamesWithGOIDs,T1,T2). %Case 2: Name has NO ID, so check to see if it's similar to a protein domain that DOES have an ID. It IS similar checkproteinswithoutids(NamesWithGOIDs,[Name|T1],[null|T2]) :- checksequencesimilarity(NamesWithGOIDs,Name), checkproteinswithoutids(NamesWithGOIDs,T1,T2). %Case 3: Name has NO ID, so check to see if it's similar to a protein domain that DOES have an ID. It is NOT similar. %we can't no find the least upper bound, so fail. checkproteinswithoutids(NamesWithGOIDs,[Name|T1],[null|T2]) :- not checksequencesimilarity(NamesWithGOIDs,Name), fail. %Case 4: Base case. checkproteinswithoutids(NamesWithGOIDs,[],[]). %checksequencesimilarity(NamesWithGOIDs,Name) :- Succeeds if Name is name of a protein that has a sequence similarity % > 60% with a protein that DOES have an ID number in NamesWithGOIDs. %Case 1: We have a match with a protein that does have an ID. checksequencesimilarity([ProteinWithID|T],ProteinWithoutID) :- sequencescore(ProteinWithID,ProteinWithoutID,X,Y) ; sequencescore(ProteinWithoutID,ProteinWithID,X,Y), X > 60. %Case 2: We have no match with a protein that does have an ID, keep searching through the list. checksequencesimilarity([ProteinWithID|T],ProteinWithoutID) :- not (sequencescore(ProteinWithID,ProteinWithoutID,X,Y) ; sequencescore(ProteinWithoutID,ProteinWithID,X,Y), X > 60), checksequencesimilarity(T,ProteinWithoutID). %Case 3: Base case. checksequencesimilarity([],ProteinWithoutID) :- fail. %sequencescore(Protein1,Protein2,SequenceScore,StructureScore) :- SequenceScore is a percentage simialrity %in sequence between the two proteins. sequencescore('1f2dC1','1f2dD1',100,98.27). sequencescore('1ttpB2','1f2dA1',11,80.85). sequencescore('1ttpB2','1c9dB2',100,95.43). sequencescore('1ttpB2','1f2dC1',11,81.01). sequencescore('1ttpB2','1cw2B2',100,95.62). sequencescore('1ttpB2','1f2dB1',12,80.83). sequencescore('1ttpB2','1tdj01',17,83.28). sequencescore('1ttpB2','1c29B2',100,95.21). sequencescore('1ttpB2','1c8vB2',100,95.22). sequencescore('1ttpB2','1jbqA1',18,84.43). sequencescore('1ttpB2','1oasB1',19,84.77). sequencescore('1ttpB2','1fcjB1',20,85.35). sequencescore('1ttpB2','1cx9B2',100,95.43). sequencescore('1ttpB2','2wsyB2',100,95.05). sequencescore('1ttpB2','1jbqD1',18,84.40). sequencescore('1ttpB2','1jbqC1',18,84.42). sequencescore('1ttpB2','1jbqB1',18,84.46). sequencescore('1ttpB2','1wsyB2',100,94.93). sequencescore('1ttpB2','1qopB2',100,95.93). sequencescore('1ttpB2','1d6sB1',20,84.80). sequencescore('1ttpB2','1fcjA1',20,85.37). sequencescore('1ttpB2','1a5sB2',100,96.41). sequencescore('1ttpB2','1f2dD1',11,81.23). sequencescore('1ttpB2','1fcjD1',20,85.45). sequencescore('1ttpB2','1jbqF1',17,84.43). sequencescore('1ttpB2','1oasA1',19,84.76). sequencescore('1ttpB2','1d6sA1',20,84.80). sequencescore('1ttpB2','1jbqE1',18,84.46). sequencescore('1ttpB2','1fcjC1',20,85.25). sequencescore('1ttpB2','2tsyB2',100,95.83). sequencescore('1c8vB2','1f2dA1',11,81.05). sequencescore('1c8vB2','1c9dB2',100,99.06). sequencescore('1c8vB2','1f2dC1',11,81.19). sequencescore('1c8vB2','1f2dB1',11,81.11). sequencescore('1c8vB2','1tdj01',18,83.86). sequencescore('1c8vB2','1c29B2',100,98.66). sequencescore('1c8vB2','1jbqA1',18,84.60). sequencescore('1c8vB2','1oasB1',19,84.63). sequencescore('1c8vB2','1fcjB1',20,85.30). sequencescore('1c8vB2','1cx9B2',100,98.68). sequencescore('1c8vB2','2wsyB2',100,95.95). sequencescore('1c8vB2','1jbqD1',18,84.62). sequencescore('1c8vB2','1jbqC1',18,84.61). sequencescore('1c8vB2','1jbqB1',18,84.62). sequencescore('1c8vB2','1qopB2',100,97.82). sequencescore('1c8vB2','1d6sB1',20,84.76). sequencescore('1c8vB2','1fcjA1',20,85.32). sequencescore('1c8vB2','1a5sB2',100,97.54). sequencescore('1c8vB2','1f2dD1',12,81.59). sequencescore('1c8vB2','1fcjD1',20,85.36). sequencescore('1c8vB2','1jbqF1',18,84.60). sequencescore('1c8vB2','1oasA1',19,84.64). sequencescore('1c8vB2','1d6sA1',19,84.74). sequencescore('1c8vB2','1jbqE1',18,84.73). sequencescore('1c8vB2','1fcjC1',20,85.22). sequencescore('1qoqB2','1f2dC1',11,81.26). sequencescore('1qoqB2','1ttpB2',100,95.81). sequencescore('1qoqB2','1c8vB2',100,97.30). sequencescore('1qoqB2','1fcjB1',20,85.50). sequencescore('1qoqB2','2wsyB2',100,95.78). sequencescore('1qoqB2','2tysB2',100,97.65). sequencescore('1qoqB2','1fcjA1',20,85.49). sequencescore('1qoqB2','1a5sB2',100,97.52). sequencescore('1qoqB2','1f2dD1',11,81.48). sequencescore('1qoqB2','1fcjD1',20,85.48). sequencescore('1qoqB2','2trsB2',100,96.83). sequencescore('1qoqB2','1a5aB2',100,97.79). sequencescore('1qoqB2','1jbqF1',17,84.68). sequencescore('1qoqB2','1oasA1',20,84.84). sequencescore('1qoqB2','1a5bB2',100,97.84). sequencescore('1qoqB2','1d6sA1',19,84.96). sequencescore('1qoqB2','1a50B2',100,97.91). sequencescore('1qoqB2','1fuyB2',100,97.75). sequencescore('1qoqB2','2tsyB2',100,96.37). sequencescore('1qoqB2','1f2dA1',11,81.05). sequencescore('1qoqB2','1c9dB2',100,97.14). sequencescore('1qoqB2','1ubsB2',100,97.53). sequencescore('1qoqB2','1cw2B2',100,97.52). sequencescore('1qoqB2','1f2dB1',11,81.20). sequencescore('1qoqB2','1tdj01',17,84.09). sequencescore('1qoqB2','1c29B2',100,96.97). sequencescore('1qoqB2','1oasB1',20,84.85). sequencescore('1qoqB2','1jbqA1',18,84.68). sequencescore('1qoqB2','1cx9B2',100,97.14). sequencescore('1qoqB2','1ttqB2',100,97.13). sequencescore('1qoqB2','1jbqD1',18,84.69). sequencescore('1qoqB2','1wsyB2',100,95.69). sequencescore('1qoqB2','1qopB2',100,98.52). sequencescore('1qoqB2','1jbqB1',18,84.71). sequencescore('1qoqB2','1jbqC1',18,84.67). sequencescore('1qoqB2','1beuB2',100,98.08). sequencescore('1qoqB2','1d6sB1',20,85.10). sequencescore('1qoqB2','1bksB2',100,97.48). sequencescore('1qoqB2','1jbqE1',18,84.71). sequencescore('1qoqB2','1fcjC1',20,85.37). sequencescore('1fcjB1','1f2dA1',15,82.22). sequencescore('1fcjB1','1f2dC1',17,82.31). sequencescore('1fcjB1','1f2dD1',15,82.57). sequencescore('1fcjB1','1f2dB1',17,82.29). sequencescore('1fcjB1','1jbqA1',37,91.28). sequencescore('1fcjB1','1jbqF1',37,91.42). sequencescore('1fcjB1','1jbqD1',37,91.24). sequencescore('1fcjB1','1jbqE1',37,91.29). sequencescore('1fcjB1','1fcjC1',100,99.10). sequencescore('1fcjB1','1jbqB1',37,91.31). sequencescore('1fcjB1','1jbqC1',37,91.29). sequencescore('2wsyB2','1f2dA1',12,80.92). sequencescore('2wsyB2','1f2dC1',12,81.02). sequencescore('2wsyB2','1f2dB1',12,81.18). sequencescore('2wsyB2','1tdj01',18,84.33). sequencescore('2wsyB2','1jbqA1',18,84.45). sequencescore('2wsyB2','1oasB1',19,84.40). sequencescore('2wsyB2','1fcjB1',20,85.41). sequencescore('2wsyB2','1jbqD1',18,84.42). sequencescore('2wsyB2','1jbqC1',18,84.42). sequencescore('2wsyB2','1jbqB1',18,84.45). sequencescore('2wsyB2','1qopB2',100,96.18). sequencescore('2wsyB2','1d6sB1',19,84.58). sequencescore('2wsyB2','1fcjA1',20,85.45). sequencescore('2wsyB2','1f2dD1',11,81.21). sequencescore('2wsyB2','1fcjD1',20,85.37). sequencescore('2wsyB2','1oasA1',19,84.40). sequencescore('2wsyB2','1jbqF1',17,84.43). sequencescore('2wsyB2','1d6sA1',19,84.60). sequencescore('2wsyB2','1jbqE1',18,84.45). sequencescore('2wsyB2','1fcjC1',20,85.36). sequencescore('2tysB2','1f2dC1',11,81.11). sequencescore('2tysB2','1ttpB2',100,95.99). sequencescore('2tysB2','1c8vB2',100,96.91). sequencescore('2tysB2','1fcjB1',20,86.00). sequencescore('2tysB2','2wsyB2',100,96.04). sequencescore('2tysB2','1fcjA1',20,86.11). sequencescore('2tysB2','1a5sB2',100,97.68). sequencescore('2tysB2','1f2dD1',11,81.55). sequencescore('2tysB2','1fcjD1',20,85.90). sequencescore('2tysB2','2trsB2',100,97.37). sequencescore('2tysB2','1jbqF1',18,85.23). sequencescore('2tysB2','1oasA1',19,85.28). sequencescore('2tysB2','1a5bB2',100,97.48). sequencescore('2tysB2','1d6sA1',19,85.54). sequencescore('2tysB2','1a50B2',100,97.60). sequencescore('2tysB2','1fuyB2',100,97.10). sequencescore('2tysB2','2tsyB2',100,97.20). sequencescore('2tysB2','1c9dB2',100,96.93). sequencescore('2tysB2','1f2dA1',11,81.02). sequencescore('2tysB2','1cw2B2',100,97.16). sequencescore('2tysB2','1tdj01',16,82.85). sequencescore('2tysB2','1f2dB1',11,81.23). sequencescore('2tysB2','1c29B2',100,96.79). sequencescore('2tysB2','1oasB1',19,85.28). sequencescore('2tysB2','1jbqA1',18,85.25). sequencescore('2tysB2','1cx9B2',100,96.87). sequencescore('2tysB2','1ttqB2',100,96.98). sequencescore('2tysB2','1jbqD1',18,85.27). sequencescore('2tysB2','1wsyB2',100,96.11). sequencescore('2tysB2','1qopB2',100,97.46). sequencescore('2tysB2','1jbqB1',18,85.26). sequencescore('2tysB2','1jbqC1',18,85.22). sequencescore('2tysB2','1d6sB1',19,85.53). sequencescore('2tysB2','1bksB2',100,97.76). sequencescore('2tysB2','1jbqE1',18,85.30). sequencescore('2tysB2','1fcjC1',20,85.81). sequencescore('1fcjA1','1f2dA1',16,82.32). sequencescore('1fcjA1','1f2dC1',17,82.37). sequencescore('1fcjA1','1f2dD1',16,82.74). sequencescore('1fcjA1','1f2dB1',17,82.42). sequencescore('1fcjA1','1jbqA1',37,91.40). sequencescore('1fcjA1','1fcjD1',100,99.29). sequencescore('1fcjA1','1fcjB1',100,99.77). sequencescore('1fcjA1','1jbqF1',38,91.50). sequencescore('1fcjA1','1jbqD1',37,91.42). sequencescore('1fcjA1','1jbqE1',37,91.47). sequencescore('1fcjA1','1fcjC1',100,99.26). sequencescore('1fcjA1','1jbqB1',38,91.53). sequencescore('1fcjA1','1jbqC1',38,91.54). sequencescore('1a5sB2','1f2dA1',11,80.89). sequencescore('1a5sB2','1c9dB2',100,97.64). sequencescore('1a5sB2','1f2dC1',11,81.11). sequencescore('1a5sB2','1f2dB1',11,81.08). sequencescore('1a5sB2','1tdj01',18,84.18). sequencescore('1a5sB2','1c29B2',100,97.54). sequencescore('1a5sB2','1jbqA1',17,84.93). sequencescore('1a5sB2','1oasB1',19,85.29). sequencescore('1a5sB2','1fcjB1',20,85.95). sequencescore('1a5sB2','1cx9B2',100,97.61). sequencescore('1a5sB2','2wsyB2',100,96.60). sequencescore('1a5sB2','1jbqD1',18,84.93). sequencescore('1a5sB2','1jbqC1',18,84.96). sequencescore('1a5sB2','1jbqB1',18,84.98). sequencescore('1a5sB2','1qopB2',100,98.09). sequencescore('1a5sB2','1d6sB1',20,85.37). sequencescore('1a5sB2','1fcjA1',20,85.99). sequencescore('1a5sB2','1f2dD1',12,81.46). sequencescore('1a5sB2','1fcjD1',20,85.95). sequencescore('1a5sB2','1jbqF1',18,84.95). sequencescore('1a5sB2','1oasA1',20,85.27). sequencescore('1a5sB2','1d6sA1',19,85.38). sequencescore('1a5sB2','1jbqE1',18,85.07). sequencescore('1a5sB2','1fcjC1',20,85.80). sequencescore('1fcjD1','1f2dA1',16,82.45). sequencescore('1fcjD1','1f2dC1',16,82.65). sequencescore('1fcjD1','1f2dD1',16,82.86). sequencescore('1fcjD1','1f2dB1',17,82.56). sequencescore('1fcjD1','1jbqA1',37,91.40). sequencescore('1fcjD1','1fcjB1',100,99.28). sequencescore('1fcjD1','1jbqF1',37,91.43). sequencescore('1fcjD1','1jbqD1',37,91.27). sequencescore('1fcjD1','1jbqE1',37,91.41). sequencescore('1fcjD1','1fcjC1',100,99.73). sequencescore('1fcjD1','1jbqB1',37,91.38). sequencescore('1fcjD1','1jbqC1',37,91.30). sequencescore('2trsB2','1f2dC1',11,81.04). sequencescore('2trsB2','1ttpB2',100,96.19). sequencescore('2trsB2','1c8vB2',100,96.36). sequencescore('2trsB2','1fcjB1',20,86.03). sequencescore('2trsB2','2wsyB2',100,95.71). sequencescore('2trsB2','1fcjA1',20,86.08). sequencescore('2trsB2','1a5sB2',100,97.14). sequencescore('2trsB2','1f2dD1',11,81.43). sequencescore('2trsB2','1fcjD1',20,86.04). sequencescore('2trsB2','1jbqF1',18,85.01). sequencescore('2trsB2','1oasA1',20,85.24). sequencescore('2trsB2','1d6sA1',20,85.45). sequencescore('2trsB2','1a50B2',100,97.15). sequencescore('2trsB2','1fuyB2',100,96.63). sequencescore('2trsB2','2tsyB2',100,97.41). sequencescore('2trsB2','1c9dB2',100,96.38). sequencescore('2trsB2','1f2dA1',11,80.90). sequencescore('2trsB2','1cw2B2',100,96.62). sequencescore('2trsB2','1tdj01',17,83.79). sequencescore('2trsB2','1f2dB1',11,81.14). sequencescore('2trsB2','1c29B2',100,96.30). sequencescore('2trsB2','1oasB1',19,85.28). sequencescore('2trsB2','1jbqA1',18,85.14). sequencescore('2trsB2','1cx9B2',100,96.38). sequencescore('2trsB2','1jbqD1',18,85.14). sequencescore('2trsB2','1wsyB2',100,95.50). sequencescore('2trsB2','1qopB2',100,96.93). sequencescore('2trsB2','1jbqB1',18,85.15). sequencescore('2trsB2','1jbqC1',18,85.01). sequencescore('2trsB2','1d6sB1',19,85.56). sequencescore('2trsB2','1bksB2',100,97.07). sequencescore('2trsB2','1jbqE1',18,85.17). sequencescore('2trsB2','1fcjC1',20,85.92). sequencescore('1a5aB2','1f2dC1',11,81.38). sequencescore('1a5aB2','1ttpB2',100,96.10). sequencescore('1a5aB2','1c8vB2',100,97.42). sequencescore('1a5aB2','1fcjB1',20,85.67). sequencescore('1a5aB2','2wsyB2',100,96.42). sequencescore('1a5aB2','2tysB2',100,97.28). sequencescore('1a5aB2','1fcjA1',20,85.71). sequencescore('1a5aB2','1a5sB2',100,98.01). sequencescore('1a5aB2','1f2dD1',11,81.63). sequencescore('1a5aB2','1fcjD1',20,85.63). sequencescore('1a5aB2','2trsB2',100,96.73). sequencescore('1a5aB2','1jbqF1',18,84.64). sequencescore('1a5aB2','1oasA1',19,84.84). sequencescore('1a5aB2','1a5bB2',100,98.73). sequencescore('1a5aB2','1d6sA1',19,85.06). sequencescore('1a5aB2','1a50B2',100,98.17). sequencescore('1a5aB2','1fuyB2',100,97.38). sequencescore('1a5aB2','2tsyB2',100,96.19). sequencescore('1a5aB2','1f2dA1',11,81.08). sequencescore('1a5aB2','1c9dB2',100,97.45). sequencescore('1a5aB2','1ubsB2',100,97.40). sequencescore('1a5aB2','1cw2B2',100,97.76). sequencescore('1a5aB2','1f2dB1',11,81.29). sequencescore('1a5aB2','1tdj01',17,83.79). sequencescore('1a5aB2','1c29B2',100,97.33). sequencescore('1a5aB2','1oasB1',19,84.86). sequencescore('1a5aB2','1jbqA1',17,84.73). sequencescore('1a5aB2','1cx9B2',100,97.60). sequencescore('1a5aB2','1ttqB2',100,97.55). sequencescore('1a5aB2','1jbqD1',17,84.74). sequencescore('1a5aB2','1wsyB2',100,95.97). sequencescore('1a5aB2','1qopB2',100,98.08). sequencescore('1a5aB2','1jbqB1',17,84.64). sequencescore('1a5aB2','1jbqC1',17,84.61). sequencescore('1a5aB2','1beuB2',100,98.77). sequencescore('1a5aB2','1d6sB1',19,85.11). sequencescore('1a5aB2','1bksB2',100,97.51). sequencescore('1a5aB2','1jbqE1',18,84.67). sequencescore('1a5aB2','1fcjC1',20,85.54). sequencescore('1jbqF1','1f2dA1',15,81.77). sequencescore('1jbqF1','1f2dC1',16,81.64). sequencescore('1jbqF1','1f2dD1',16,81.73). sequencescore('1jbqF1','1f2dB1',15,81.47). sequencescore('1oasA1','1f2dA1',15,81.67). sequencescore('1oasA1','1f2dC1',16,81.69). sequencescore('1oasA1','1f2dB1',15,81.91). sequencescore('1oasA1','1jbqA1',36,90.85). sequencescore('1oasA1','1oasB1',100,99.77). sequencescore('1oasA1','1fcjB1',100,98.56). sequencescore('1oasA1','1jbqD1',36,90.84). sequencescore('1oasA1','1jbqC1',36,90.86). sequencescore('1oasA1','1jbqB1',36,90.86). sequencescore('1oasA1','1d6sB1',100,98.64). sequencescore('1oasA1','1fcjA1',100,98.66). sequencescore('1oasA1','1f2dD1',16,81.95). sequencescore('1oasA1','1fcjD1',100,98.65). sequencescore('1oasA1','1jbqF1',36,90.88). sequencescore('1oasA1','1d6sA1',100,98.71). sequencescore('1oasA1','1jbqE1',36,90.86). sequencescore('1oasA1','1fcjC1',100,98.47). sequencescore('1a5bB2','1f2dC1',11,81.52). sequencescore('1a5bB2','1ttpB2',100,96.29). sequencescore('1a5bB2','1c8vB2',100,97.49). sequencescore('1a5bB2','1fcjB1',20,85.84). sequencescore('1a5bB2','2wsyB2',100,96.73). sequencescore('1a5bB2','1fcjA1',20,85.87). sequencescore('1a5bB2','1a5sB2',100,98.04). sequencescore('1a5bB2','1f2dD1',11,81.92). sequencescore('1a5bB2','1fcjD1',20,85.81). sequencescore('1a5bB2','2trsB2',100,96.99). sequencescore('1a5bB2','1jbqF1',18,84.69). sequencescore('1a5bB2','1oasA1',19,85.14). sequencescore('1a5bB2','1d6sA1',19,85.22). sequencescore('1a5bB2','1a50B2',100,98.23). sequencescore('1a5bB2','1fuyB2',100,97.48). sequencescore('1a5bB2','2tsyB2',100,96.39). sequencescore('1a5bB2','1c9dB2',100,97.50). sequencescore('1a5bB2','1f2dA1',11,81.34). sequencescore('1a5bB2','1cw2B2',100,97.85). sequencescore('1a5bB2','1tdj01',17,84.03). sequencescore('1a5bB2','1f2dB1',11,81.54). sequencescore('1a5bB2','1c29B2',100,97.39). sequencescore('1a5bB2','1oasB1',20,85.15). sequencescore('1a5bB2','1jbqA1',18,84.80). sequencescore('1a5bB2','1cx9B2',100,97.60). sequencescore('1a5bB2','1ttqB2',100,97.77). sequencescore('1a5bB2','1jbqD1',18,84.80). sequencescore('1a5bB2','1wsyB2',100,96.37). sequencescore('1a5bB2','1qopB2',100,98.10). sequencescore('1a5bB2','1jbqB1',18,84.82). sequencescore('1a5bB2','1jbqC1',18,84.71). sequencescore('1a5bB2','1d6sB1',19,85.28). sequencescore('1a5bB2','1bksB2',100,97.89). sequencescore('1a5bB2','1jbqE1',18,84.73). sequencescore('1a5bB2','1fcjC1',20,85.67). sequencescore('1d6sA1','1f2dA1',15,81.55). sequencescore('1d6sA1','1fcjA1',100,98.54). sequencescore('1d6sA1','1d6sB1',100,99.57). sequencescore('1d6sA1','1f2dC1',15,81.54). sequencescore('1d6sA1','1f2dD1',15,81.96). sequencescore('1d6sA1','1f2dB1',15,81.83). sequencescore('1d6sA1','1jbqA1',36,90.81). sequencescore('1d6sA1','1fcjD1',100,98.48). sequencescore('1d6sA1','1fcjB1',100,98.43). sequencescore('1d6sA1','1jbqF1',36,90.85). sequencescore('1d6sA1','1jbqD1',36,90.80). sequencescore('1d6sA1','1jbqE1',36,90.85). sequencescore('1d6sA1','1fcjC1',100,98.26). sequencescore('1d6sA1','1jbqB1',36,90.82). sequencescore('1d6sA1','1jbqC1',36,90.82). sequencescore('1a50B2','1f2dA1',11,81.03). sequencescore('1a50B2','1c9dB2',100,98.01). sequencescore('1a50B2','1f2dC1',11,81.18). sequencescore('1a50B2','1ttpB2',100,96.26). sequencescore('1a50B2','1cw2B2',100,98.30). sequencescore('1a50B2','1f2dB1',11,81.21). sequencescore('1a50B2','1tdj01',17,83.98). sequencescore('1a50B2','1c29B2',100,97.79). sequencescore('1a50B2','1c8vB2',100,97.98). sequencescore('1a50B2','1jbqA1',18,84.98). sequencescore('1a50B2','1oasB1',19,85.15). sequencescore('1a50B2','1fcjB1',20,85.78). sequencescore('1a50B2','2wsyB2',100,96.65). sequencescore('1a50B2','1cx9B2',100,97.90). sequencescore('1a50B2','1jbqD1',18,84.88). sequencescore('1a50B2','1jbqC1',18,84.89). sequencescore('1a50B2','1jbqB1',18,84.91). sequencescore('1a50B2','1qopB2',100,98.54). sequencescore('1a50B2','1wsyB2',100,96.34). sequencescore('1a50B2','1d6sB1',20,85.34). sequencescore('1a50B2','1fcjA1',20,85.78). sequencescore('1a50B2','1a5sB2',100,98.93). sequencescore('1a50B2','1f2dD1',11,81.48). sequencescore('1a50B2','1fcjD1',20,85.70). sequencescore('1a50B2','1jbqF1',18,84.89). sequencescore('1a50B2','1oasA1',20,85.10). sequencescore('1a50B2','1d6sA1',19,85.30). sequencescore('1a50B2','1jbqE1',18,84.91). sequencescore('1a50B2','1fcjC1',20,85.59). sequencescore('1a50B2','2tsyB2',100,96.27). sequencescore('1fuyB2','1f2dA1',11,80.68). sequencescore('1fuyB2','1c9dB2',100,96.93). sequencescore('1fuyB2','1f2dC1',11,80.85). sequencescore('1fuyB2','1ttpB2',100,95.73). sequencescore('1fuyB2','1cw2B2',100,97.27). sequencescore('1fuyB2','1f2dB1',11,80.81). sequencescore('1fuyB2','1tdj01',17,84.00). sequencescore('1fuyB2','1c29B2',100,96.82). sequencescore('1fuyB2','1c8vB2',100,97.04). sequencescore('1fuyB2','1jbqA1',18,84.65). sequencescore('1fuyB2','1oasB1',19,84.98). sequencescore('1fuyB2','1fcjB1',20,85.60). sequencescore('1fuyB2','2wsyB2',100,95.84). sequencescore('1fuyB2','1cx9B2',100,96.87). sequencescore('1fuyB2','1jbqD1',18,84.65). sequencescore('1fuyB2','1jbqC1',18,84.64). sequencescore('1fuyB2','1jbqB1',18,84.67). sequencescore('1fuyB2','1qopB2',100,97.99). sequencescore('1fuyB2','1wsyB2',100,95.79). sequencescore('1fuyB2','1fcjA1',20,85.61). sequencescore('1fuyB2','1d6sB1',19,85.12). sequencescore('1fuyB2','1a5sB2',100,97.79). sequencescore('1fuyB2','1f2dD1',11,81.24). sequencescore('1fuyB2','1fcjD1',20,85.58). sequencescore('1fuyB2','1jbqF1',18,84.66). sequencescore('1fuyB2','1oasA1',19,84.99). sequencescore('1fuyB2','1d6sA1',20,85.06). sequencescore('1fuyB2','1jbqE1',18,84.68). sequencescore('1fuyB2','1fcjC1',20,85.41). sequencescore('1fuyB2','1a50B2',100,98.01). sequencescore('1fuyB2','2tsyB2',100,95.95). sequencescore('2tsyB2','1f2dA1',11,80.91). sequencescore('2tsyB2','1c9dB2',100,95.95). sequencescore('2tsyB2','1f2dC1',11,80.99). sequencescore('2tsyB2','1cw2B2',100,96.03). sequencescore('2tsyB2','1f2dB1',11,81.00). sequencescore('2tsyB2','1tdj01',17,83.45). sequencescore('2tsyB2','1c29B2',100,95.87). sequencescore('2tsyB2','1c8vB2',100,95.85). sequencescore('2tsyB2','1jbqA1',18,84.90). sequencescore('2tsyB2','1oasB1',20,85.09). sequencescore('2tsyB2','1fcjB1',20,85.74). sequencescore('2tsyB2','1cx9B2',100,95.81). sequencescore('2tsyB2','2wsyB2',100,95.21). sequencescore('2tsyB2','1jbqD1',18,84.95). sequencescore('2tsyB2','1jbqC1',18,84.87). sequencescore('2tsyB2','1jbqB1',18,84.91). sequencescore('2tsyB2','1wsyB2',100,95.11). sequencescore('2tsyB2','1qopB2',100,96.24). sequencescore('2tsyB2','1d6sB1',19,85.27). sequencescore('2tsyB2','1fcjA1',20,85.81). sequencescore('2tsyB2','1a5sB2',100,96.42). sequencescore('2tsyB2','1f2dD1',11,81.25). sequencescore('2tsyB2','1fcjD1',20,85.68). sequencescore('2tsyB2','1jbqF1',17,84.85). sequencescore('2tsyB2','1oasA1',19,85.08). sequencescore('2tsyB2','1d6sA1',19,85.23). sequencescore('2tsyB2','1jbqE1',18,84.91). sequencescore('2tsyB2','1fcjC1',20,85.60). sequencescore('1f2dA1','1f2dC1',100,97.49). sequencescore('1f2dA1','1f2dD1',100,97.00). sequencescore('1f2dA1','1f2dB1',100,97.00). sequencescore('1c9dB2','1f2dA1',12,80.96). sequencescore('1c9dB2','1f2dC1',12,81.15). sequencescore('1c9dB2','1f2dB1',12,81.10). sequencescore('1c9dB2','1tdj01',17,84.11). sequencescore('1c9dB2','1jbqA1',17,84.60). sequencescore('1c9dB2','1oasB1',20,84.67). sequencescore('1c9dB2','1cx9B2',100,98.91). sequencescore('1c9dB2','2wsyB2',100,96.07). sequencescore('1c9dB2','1fcjB1',20,85.37). sequencescore('1c9dB2','1jbqD1',18,84.64). sequencescore('1c9dB2','1jbqC1',18,84.72). sequencescore('1c9dB2','1jbqB1',18,84.61). sequencescore('1c9dB2','1qopB2',100,97.86). sequencescore('1c9dB2','1d6sB1',19,84.94). sequencescore('1c9dB2','1fcjA1',20,85.35). sequencescore('1c9dB2','1f2dD1',12,81.55). sequencescore('1c9dB2','1fcjD1',20,85.38). sequencescore('1c9dB2','1jbqF1',18,84.63). sequencescore('1c9dB2','1oasA1',19,84.55). sequencescore('1c9dB2','1d6sA1',19,84.88). sequencescore('1c9dB2','1jbqE1',18,84.75). sequencescore('1c9dB2','1fcjC1',20,85.24). sequencescore('1ubsB2','1f2dC1',11,81.24). sequencescore('1ubsB2','1ttpB2',100,96.38). sequencescore('1ubsB2','1c8vB2',100,97.14). sequencescore('1ubsB2','1fcjB1',20,85.91). sequencescore('1ubsB2','2wsyB2',100,96.22). sequencescore('1ubsB2','2tysB2',100,97.79). sequencescore('1ubsB2','1fcjA1',20,85.89). sequencescore('1ubsB2','1a5sB2',100,98.13). sequencescore('1ubsB2','1f2dD1',11,81.64). sequencescore('1ubsB2','1fcjD1',20,85.84). sequencescore('1ubsB2','2trsB2',100,97.25). sequencescore('1ubsB2','1jbqF1',18,84.85). sequencescore('1ubsB2','1oasA1',20,85.22). sequencescore('1ubsB2','1a5bB2',100,97.75). sequencescore('1ubsB2','1d6sA1',19,85.32). sequencescore('1ubsB2','1a50B2',100,98.13). sequencescore('1ubsB2','1fuyB2',100,97.52). sequencescore('1ubsB2','2tsyB2',100,96.53). sequencescore('1ubsB2','1f2dA1',11,80.99). sequencescore('1ubsB2','1c9dB2',100,97.14). sequencescore('1ubsB2','1cw2B2',100,97.43). sequencescore('1ubsB2','1f2dB1',11,81.32). sequencescore('1ubsB2','1tdj01',17,83.76). sequencescore('1ubsB2','1c29B2',100,96.93). sequencescore('1ubsB2','1oasB1',19,85.25). sequencescore('1ubsB2','1jbqA1',18,84.87). sequencescore('1ubsB2','1cx9B2',100,97.10). sequencescore('1ubsB2','1ttqB2',100,97.65). sequencescore('1ubsB2','1jbqD1',18,84.85). sequencescore('1ubsB2','1wsyB2',100,96.32). sequencescore('1ubsB2','1qopB2',100,97.94). sequencescore('1ubsB2','1jbqB1',18,84.88). sequencescore('1ubsB2','1jbqC1',18,84.87). sequencescore('1ubsB2','1d6sB1',19,85.34). sequencescore('1ubsB2','1bksB2',100,98.31). sequencescore('1ubsB2','1jbqE1',18,84.89). sequencescore('1ubsB2','1fcjC1',20,85.76). sequencescore('1cw2B2','1f2dA1',11,81.00). sequencescore('1cw2B2','1c9dB2',100,99.09). sequencescore('1cw2B2','1f2dC1',12,81.17). sequencescore('1cw2B2','1f2dB1',12,81.11). sequencescore('1cw2B2','1tdj01',18,84.11). sequencescore('1cw2B2','1c29B2',100,98.72). sequencescore('1cw2B2','1c8vB2',100,99.05). sequencescore('1cw2B2','1jbqA1',17,84.78). sequencescore('1cw2B2','1oasB1',20,84.69). sequencescore('1cw2B2','1fcjB1',20,85.50). sequencescore('1cw2B2','1cx9B2',100,98.91). sequencescore('1cw2B2','2wsyB2',100,96.18). sequencescore('1cw2B2','1jbqD1',18,84.69). sequencescore('1cw2B2','1jbqC1',18,84.67). sequencescore('1cw2B2','1jbqB1',18,84.68). sequencescore('1cw2B2','1qopB2',100,98.20). sequencescore('1cw2B2','1d6sB1',19,85.04). sequencescore('1cw2B2','1fcjA1',20,85.50). sequencescore('1cw2B2','1a5sB2',100,97.85). sequencescore('1cw2B2','1f2dD1',12,81.58). sequencescore('1cw2B2','1fcjD1',20,85.50). sequencescore('1cw2B2','1jbqF1',18,84.66). sequencescore('1cw2B2','1oasA1',19,84.68). sequencescore('1cw2B2','1d6sA1',20,84.83). sequencescore('1cw2B2','1jbqE1',18,84.72). sequencescore('1cw2B2','1fcjC1',20,85.37). sequencescore('1f2dB1','1f2dC1',100,97.28). sequencescore('1f2dB1','1f2dD1',100,97.37). sequencescore('1tdj01','1f2dA1',15,80.46). sequencescore('1tdj01','1f2dC1',16,80.49). sequencescore('1tdj01','1f2dB1',15,80.40). sequencescore('1tdj01','1jbqA1',19,84.70). sequencescore('1tdj01','1oasB1',19,85.14). sequencescore('1tdj01','1fcjB1',20,86.38). sequencescore('1tdj01','1jbqD1',19,84.73). sequencescore('1tdj01','1jbqC1',19,84.70). sequencescore('1tdj01','1jbqB1',19,84.73). sequencescore('1tdj01','1d6sB1',19,85.13). sequencescore('1tdj01','1fcjA1',20,86.56). sequencescore('1tdj01','1f2dD1',15,80.72). sequencescore('1tdj01','1fcjD1',20,86.48). sequencescore('1tdj01','1oasA1',19,85.09). sequencescore('1tdj01','1jbqF1',19,84.80). sequencescore('1tdj01','1d6sA1',19,85.21). sequencescore('1tdj01','1jbqE1',19,84.75). sequencescore('1tdj01','1fcjC1',20,86.32). sequencescore('1c29B2','1f2dA1',11,80.89). sequencescore('1c29B2','1c9dB2',100,98.72). sequencescore('1c29B2','1f2dC1',12,81.03). sequencescore('1c29B2','1f2dB1',12,80.98). sequencescore('1c29B2','1tdj01',18,84.01). sequencescore('1c29B2','1jbqA1',18,84.72). sequencescore('1c29B2','1oasB1',20,84.64). sequencescore('1c29B2','1fcjB1',20,85.44). sequencescore('1c29B2','1cx9B2',100,98.67). sequencescore('1c29B2','2wsyB2',100,96.12). sequencescore('1c29B2','1jbqD1',18,84.83). sequencescore('1c29B2','1jbqC1',18,84.82). sequencescore('1c29B2','1jbqB1',18,84.72). sequencescore('1c29B2','1qopB2',100,97.56). sequencescore('1c29B2','1d6sB1',19,84.97). sequencescore('1c29B2','1fcjA1',20,85.43). sequencescore('1c29B2','1f2dD1',12,81.41). sequencescore('1c29B2','1fcjD1',20,85.45). sequencescore('1c29B2','1jbqF1',17,84.70). sequencescore('1c29B2','1oasA1',20,84.66). sequencescore('1c29B2','1d6sA1',19,84.88). sequencescore('1c29B2','1jbqE1',18,84.85). sequencescore('1c29B2','1fcjC1',20,85.33). sequencescore('1oasB1','1f2dA1',15,81.68). sequencescore('1oasB1','1f2dC1',16,81.71). sequencescore('1oasB1','1f2dB1',15,81.70). sequencescore('1oasB1','1jbqA1',36,90.84). sequencescore('1oasB1','1fcjB1',100,98.55). sequencescore('1oasB1','1jbqD1',36,90.81). sequencescore('1oasB1','1jbqC1',36,90.82). sequencescore('1oasB1','1jbqB1',36,90.85). sequencescore('1oasB1','1d6sB1',100,98.64). sequencescore('1oasB1','1fcjA1',100,98.66). sequencescore('1oasB1','1f2dD1',15,81.98). sequencescore('1oasB1','1fcjD1',100,98.68). sequencescore('1oasB1','1jbqF1',36,90.88). sequencescore('1oasB1','1d6sA1',100,98.68). sequencescore('1oasB1','1jbqE1',36,90.88). sequencescore('1oasB1','1fcjC1',100,98.46). sequencescore('1jbqA1','1f2dA1',15,81.79). sequencescore('1jbqA1','1f2dC1',16,81.62). sequencescore('1jbqA1','1jbqF1',100,99.26). sequencescore('1jbqA1','1f2dD1',16,81.70). sequencescore('1jbqA1','1jbqD1',100,99.80). sequencescore('1jbqA1','1jbqE1',100,99.75). sequencescore('1jbqA1','1f2dB1',16,81.46). sequencescore('1jbqA1','1jbqC1',100,99.80). sequencescore('1jbqA1','1jbqB1',100,99.76). sequencescore('1cx9B2','1f2dA1',11,81.05). sequencescore('1cx9B2','1f2dC1',12,81.23). sequencescore('1cx9B2','1f2dB1',12,81.16). sequencescore('1cx9B2','1tdj01',18,84.06). sequencescore('1cx9B2','1jbqA1',18,84.76). sequencescore('1cx9B2','1oasB1',19,84.71). sequencescore('1cx9B2','2wsyB2',100,95.93). sequencescore('1cx9B2','1fcjB1',20,85.39). sequencescore('1cx9B2','1jbqD1',18,84.78). sequencescore('1cx9B2','1jbqC1',18,84.77). sequencescore('1cx9B2','1jbqB1',18,84.80). sequencescore('1cx9B2','1qopB2',100,97.69). sequencescore('1cx9B2','1d6sB1',19,84.89). sequencescore('1cx9B2','1fcjA1',20,85.40). sequencescore('1cx9B2','1f2dD1',12,81.53). sequencescore('1cx9B2','1fcjD1',20,85.43). sequencescore('1cx9B2','1jbqF1',18,84.66). sequencescore('1cx9B2','1oasA1',19,84.70). sequencescore('1cx9B2','1d6sA1',20,84.85). sequencescore('1cx9B2','1jbqE1',18,84.80). sequencescore('1cx9B2','1fcjC1',20,85.26). sequencescore('1ttqB2','1f2dC1',11,81.16). sequencescore('1ttqB2','1ttpB2',100,96.58). sequencescore('1ttqB2','1c8vB2',100,96.92). sequencescore('1ttqB2','1fcjB1',20,85.58). sequencescore('1ttqB2','2wsyB2',100,96.04). sequencescore('1ttqB2','1fcjA1',20,85.60). sequencescore('1ttqB2','1a5sB2',100,97.61). sequencescore('1ttqB2','1f2dD1',11,81.56). sequencescore('1ttqB2','1fcjD1',20,85.57). sequencescore('1ttqB2','2trsB2',100,97.36). sequencescore('1ttqB2','1jbqF1',18,84.46). sequencescore('1ttqB2','1oasA1',19,84.93). sequencescore('1ttqB2','1d6sA1',19,85.03). sequencescore('1ttqB2','1a50B2',100,97.78). sequencescore('1ttqB2','1fuyB2',100,97.24). sequencescore('1ttqB2','2tsyB2',100,96.84). sequencescore('1ttqB2','1c9dB2',100,96.89). sequencescore('1ttqB2','1f2dA1',11,80.96). sequencescore('1ttqB2','1cw2B2',100,97.11). sequencescore('1ttqB2','1tdj01',17,83.95). sequencescore('1ttqB2','1f2dB1',11,81.21). sequencescore('1ttqB2','1c29B2',100,96.73). sequencescore('1ttqB2','1oasB1',19,84.93). sequencescore('1ttqB2','1jbqA1',18,84.47). sequencescore('1ttqB2','1cx9B2',100,96.87). sequencescore('1ttqB2','1jbqD1',18,84.47). sequencescore('1ttqB2','1wsyB2',100,96.15). sequencescore('1ttqB2','1qopB2',100,97.55). sequencescore('1ttqB2','1jbqB1',18,84.47). sequencescore('1ttqB2','1jbqC1',18,84.44). sequencescore('1ttqB2','1d6sB1',19,85.04). sequencescore('1ttqB2','1bksB2',100,97.64). sequencescore('1ttqB2','1jbqE1',18,84.49). sequencescore('1ttqB2','1fcjC1',20,85.43). sequencescore('1jbqD1','1f2dA1',15,81.83). sequencescore('1jbqD1','1f2dC1',16,81.63). sequencescore('1jbqD1','1jbqF1',100,99.26). sequencescore('1jbqD1','1f2dD1',16,81.71). sequencescore('1jbqD1','1jbqE1',100,99.76). sequencescore('1jbqD1','1f2dB1',15,81.47). sequencescore('1wsyB2','1f2dA1',11,80.85). sequencescore('1wsyB2','1c9dB2',100,95.61). sequencescore('1wsyB2','1f2dC1',11,80.94). sequencescore('1wsyB2','1cw2B2',100,95.91). sequencescore('1wsyB2','1f2dB1',11,80.94). sequencescore('1wsyB2','1tdj01',16,82.28). sequencescore('1wsyB2','1c29B2',100,95.57). sequencescore('1wsyB2','1c8vB2',100,95.71). sequencescore('1wsyB2','1jbqA1',18,84.26). sequencescore('1wsyB2','1oasB1',20,84.54). sequencescore('1wsyB2','1fcjB1',20,85.27). sequencescore('1wsyB2','1cx9B2',100,95.79). sequencescore('1wsyB2','2wsyB2',100,95.28). sequencescore('1wsyB2','1jbqD1',18,84.24). sequencescore('1wsyB2','1jbqC1',18,84.25). sequencescore('1wsyB2','1jbqB1',18,84.26). sequencescore('1wsyB2','1qopB2',100,96.09). sequencescore('1wsyB2','1d6sB1',20,84.61). sequencescore('1wsyB2','1fcjA1',20,85.25). sequencescore('1wsyB2','1a5sB2',100,96.17). sequencescore('1wsyB2','1f2dD1',11,81.17). sequencescore('1wsyB2','1fcjD1',20,85.14). sequencescore('1wsyB2','1jbqF1',17,84.23). sequencescore('1wsyB2','1oasA1',20,84.55). sequencescore('1wsyB2','1d6sA1',19,84.63). sequencescore('1wsyB2','1jbqE1',18,84.30). sequencescore('1wsyB2','1fcjC1',20,85.05). sequencescore('1qopB2','1f2dA1',11,81.09). sequencescore('1qopB2','1f2dC1',11,81.28). sequencescore('1qopB2','1f2dB1',11,81.34). sequencescore('1qopB2','1tdj01',17,83.97). sequencescore('1qopB2','1jbqA1',18,84.74). sequencescore('1qopB2','1oasB1',19,84.93). sequencescore('1qopB2','1fcjB1',20,85.65). sequencescore('1qopB2','1jbqD1',18,84.74). sequencescore('1qopB2','1jbqC1',18,84.73). sequencescore('1qopB2','1jbqB1',18,84.75). sequencescore('1qopB2','1d6sB1',19,85.15). sequencescore('1qopB2','1fcjA1',20,85.68). sequencescore('1qopB2','1f2dD1',11,81.52). sequencescore('1qopB2','1fcjD1',20,85.65). sequencescore('1qopB2','1oasA1',20,84.85). sequencescore('1qopB2','1jbqF1',17,84.74). sequencescore('1qopB2','1d6sA1',19,85.14). sequencescore('1qopB2','1jbqE1',18,84.76). sequencescore('1qopB2','1fcjC1',20,85.52). sequencescore('1jbqB1','1f2dA1',15,81.85). sequencescore('1jbqB1','1f2dC1',15,81.65). sequencescore('1jbqB1','1jbqF1',100,99.28). sequencescore('1jbqB1','1f2dD1',16,81.72). sequencescore('1jbqB1','1jbqD1',100,99.78). sequencescore('1jbqB1','1jbqE1',100,99.76). sequencescore('1jbqB1','1f2dB1',15,81.49). sequencescore('1jbqB1','1jbqC1',100,99.78). sequencescore('1jbqC1','1f2dA1',15,81.74). sequencescore('1jbqC1','1f2dC1',15,81.63). sequencescore('1jbqC1','1jbqF1',100,99.26). sequencescore('1jbqC1','1f2dD1',16,81.68). sequencescore('1jbqC1','1jbqD1',100,99.80). sequencescore('1jbqC1','1jbqE1',100,99.77). sequencescore('1jbqC1','1f2dB1',15,81.46). sequencescore('1beuB2','1f2dC1',11,81.32). sequencescore('1beuB2','1ttpB2',100,96.18). sequencescore('1beuB2','1c8vB2',100,97.88). sequencescore('1beuB2','1fcjB1',20,85.73). sequencescore('1beuB2','2wsyB2',100,96.60). sequencescore('1beuB2','2tysB2',100,97.43). sequencescore('1beuB2','1fcjA1',20,85.72). sequencescore('1beuB2','1a5sB2',100,98.35). sequencescore('1beuB2','1f2dD1',11,81.72). sequencescore('1beuB2','1fcjD1',20,85.70). sequencescore('1beuB2','2trsB2',100,97.02). sequencescore('1beuB2','1jbqF1',18,84.67). sequencescore('1beuB2','1oasA1',19,84.98). sequencescore('1beuB2','1a5bB2',100,98.89). sequencescore('1beuB2','1d6sA1',20,85.14). sequencescore('1beuB2','1a50B2',100,98.63). sequencescore('1beuB2','1fuyB2',100,97.67). sequencescore('1beuB2','2tsyB2',100,96.34). sequencescore('1beuB2','1f2dA1',11,81.18). sequencescore('1beuB2','1c9dB2',100,97.86). sequencescore('1beuB2','1ubsB2',100,97.79). sequencescore('1beuB2','1cw2B2',100,98.13). sequencescore('1beuB2','1f2dB1',11,81.35). sequencescore('1beuB2','1tdj01',17,83.84). sequencescore('1beuB2','1c29B2',100,97.64). sequencescore('1beuB2','1oasB1',20,84.96). sequencescore('1beuB2','1jbqA1',17,84.69). sequencescore('1beuB2','1cx9B2',100,97.92). sequencescore('1beuB2','1ttqB2',100,97.76). sequencescore('1beuB2','1jbqD1',17,84.79). sequencescore('1beuB2','1wsyB2',100,96.08). sequencescore('1beuB2','1qopB2',100,98.43). sequencescore('1beuB2','1jbqB1',17,84.70). sequencescore('1beuB2','1jbqC1',18,84.67). sequencescore('1beuB2','1d6sB1',20,85.16). sequencescore('1beuB2','1bksB2',100,97.82). sequencescore('1beuB2','1jbqE1',18,84.69). sequencescore('1beuB2','1fcjC1',20,85.59). sequencescore('1d6sB1','1f2dA1',15,81.67). sequencescore('1d6sB1','1fcjA1',100,98.56). sequencescore('1d6sB1','1f2dC1',15,81.85). sequencescore('1d6sB1','1f2dD1',15,82.01). sequencescore('1d6sB1','1f2dB1',15,81.82). sequencescore('1d6sB1','1jbqA1',36,90.87). sequencescore('1d6sB1','1fcjD1',100,98.56). sequencescore('1d6sB1','1fcjB1',100,98.47). sequencescore('1d6sB1','1jbqF1',36,90.92). sequencescore('1d6sB1','1jbqD1',36,90.84). sequencescore('1d6sB1','1jbqE1',36,90.91). sequencescore('1d6sB1','1fcjC1',100,98.30). sequencescore('1d6sB1','1jbqB1',36,90.90). sequencescore('1d6sB1','1jbqC1',36,90.91). sequencescore('1bksB2','1f2dC1',11,81.04). sequencescore('1bksB2','1ttpB2',100,96.35). sequencescore('1bksB2','1c8vB2',100,97.10). sequencescore('1bksB2','1fcjB1',20,85.63). sequencescore('1bksB2','2wsyB2',100,96.34). sequencescore('1bksB2','1fcjA1',20,85.65). sequencescore('1bksB2','1a5sB2',100,97.91). sequencescore('1bksB2','1f2dD1',11,81.42). sequencescore('1bksB2','1fcjD1',20,85.59). sequencescore('1bksB2','1jbqF1',18,84.64). sequencescore('1bksB2','1oasA1',20,84.92). sequencescore('1bksB2','1d6sA1',20,85.08). sequencescore('1bksB2','1a50B2',100,98.07). sequencescore('1bksB2','1fuyB2',100,97.36). sequencescore('1bksB2','2tsyB2',100,96.12). sequencescore('1bksB2','1c9dB2',100,97.10). sequencescore('1bksB2','1f2dA1',11,80.78). sequencescore('1bksB2','1cw2B2',100,97.30). sequencescore('1bksB2','1tdj01',17,83.88). sequencescore('1bksB2','1f2dB1',11,81.10). sequencescore('1bksB2','1c29B2',100,96.96). sequencescore('1bksB2','1oasB1',20,84.97). sequencescore('1bksB2','1jbqA1',18,84.66). sequencescore('1bksB2','1cx9B2',100,97.17). sequencescore('1bksB2','1jbqD1',18,84.73). sequencescore('1bksB2','1wsyB2',100,96.64). sequencescore('1bksB2','1qopB2',100,97.69). sequencescore('1bksB2','1jbqB1',18,84.76). sequencescore('1bksB2','1jbqC1',18,84.64). sequencescore('1bksB2','1d6sB1',19,85.11). sequencescore('1bksB2','1jbqE1',18,84.78). sequencescore('1bksB2','1fcjC1',20,85.41). sequencescore('1jbqE1','1f2dA1',15,81.77). sequencescore('1jbqE1','1f2dC1',16,81.66). sequencescore('1jbqE1','1jbqF1',100,99.24). sequencescore('1jbqE1','1f2dD1',16,81.73). sequencescore('1jbqE1','1f2dB1',16,81.49). sequencescore('1fcjC1','1f2dA1',15,82.33). sequencescore('1fcjC1','1f2dC1',15,82.49). sequencescore('1fcjC1','1f2dD1',15,82.69). sequencescore('1fcjC1','1f2dB1',17,82.40). sequencescore('1fcjC1','1jbqA1',37,91.24). sequencescore('1fcjC1','1jbqF1',37,91.36). sequencescore('1fcjC1','1jbqD1',37,91.20). sequencescore('1fcjC1','1jbqE1',37,91.24). sequencescore('1fcjC1','1jbqB1',37,91.31). sequencescore('1fcjC1','1jbqC1',37,91.32). %sequencescore('1c4tA0','1e2o00',67,91.32). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% Code for cannotfindsemanticgeneralization/3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% If at least one protein in the input set lacks a %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% GO ID number AND does not have a similar enough %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% sequence to a protein domain whose GOID is known, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% then this predicate succeeds and returns a warning %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% message stating which protein(s) fall into this %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% category and prevent the set being merged. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % semanticgeneralization/3 succeeds if either all of the proteins in list Names have GO ID numbers, or if they do not, %all of those that do not have a sequence similarity > 60 to a protein in NamesWithGOIDs, i.e. a protein domain %whose GOID is known. But in a set of rules we need a rule to deal with the case in which semanticgeneralization/3 %FAILS because at least one protein whose GOID is not known is not similar enough in sequence to a protein whose %ID is known. cannotfindsemanticgeneralization/3 deals with this situation. %cannotfindsemanticgeneralization(Proteins,GOIDs,Message) :- Message is a message stating that the input set Proteins %cannot be merged giving a list of those proteins in the list that BOTH have no GOID AND are not similar enough in sequence %to any protein in the list whose GOID is known. cannotfindsemanticgeneralization(Proteins,GOIDs,Message) :- removeproteinswithoutids(Proteins,GOIDs,ProteinsWithGOIDs), not checkproteinswithoutids(ProteinsWithGOIDs,Proteins,GOIDs), getproteinswithoutseqsim(ProteinsWithGOIDs,Proteins,GOIDs,ProteinsWithoutSeqSim), constructmessage(ProteinsWithoutSeqSim,Message). %getproteinswithoutseqsim(ProteinsWithGOIDs,Proteins,GOIDs,ProteinsWithoutSeqSim) :- ProteinsWithoutSeqSim is a list of those %proteins in Proteins that both lack a GOID AND have a sequence similarity score < 61 with any protein in ProteinsWithGOIDs. %Case 1: Protein has a GOID, so do nothing. getproteinswithoutseqsim(ProteinsWithGOIDs,[Protein|T1],[GOID|T2],ProteinsWithoutSeqSim) :- not GOID == null, getproteinswithoutseqsim(ProteinsWithGOIDs,T1,T2,ProteinsWithoutSeqSim). %Case 2: Protein has no GOID, but it has similar sequence, so do nothing again. getproteinswithoutseqsim(ProteinsWithGOIDs,[Protein|T1],[null|T2],ProteinsWithoutSeqSim) :- checksequencesimilarity(ProteinsWithGOIDs,Protein), getproteinswithoutseqsim(ProteinsWithGOIDs,T1,T2,ProteinsWithoutSeqSim). %Case 3: Protein has no GOID, AND it does NOT have similar sequence, so add to our list. getproteinswithoutseqsim(ProteinsWithGOIDs,[Protein|T1],[null|T2],[Protein|T3]) :- not checksequencesimilarity(ProteinsWithGOIDs,Protein), getproteinswithoutseqsim(ProteinsWithGOIDs,T1,T2,T3). %Case 4: Base case. getproteinswithoutseqsim(ProteinsWithGOIDs,[],[],[]). %constructmessage(ProteinsWithoutSeqSim,Message) :- Message is the string "These protein domains cannot be merged. Proteins ... [list proteins here] ... are notsimilar in sequence to rest of input." constructmessage(ProteinsWithoutSeqSim,Message) :- converttochars(ProteinsWithoutSeqSim,CharsLists), removefirstlist(CharsLists,EditedLists,FirstList), makeandstring(EditedLists,FirstList,ConjunctionList), atom_chars('Proteins cannot be merged. Protein(s) ',Chars1), append(Chars1,ConjunctionList,NewList), atom_chars(' are not similar in sequence to rest of input.',Chars2), append(NewList,Chars2,MessageList), atom_chars(Message,MessageList). %converttochars(ProteinsWithoutSeqSim,CharsLists) :- CharsLists is a list of lists. The lists are lists of chars that %correspond to the protein domains in ProteinsWithoutSeqSim. converttochars([Term|Rest1],[Chars|Rest2]) :- atom_chars(Term,Chars), converttochars(Rest1,Rest2). converttochars([],[]). %removefirstlist(CharsLists,EditedLists,FirstList) :- EditedLists is the list of lists CharsLists, but %with the first list removed, as FirstList. The purpose of this is simply to set up the data in a way that makes it %easier for predicate makedisjunction to create a string of the disjunction of all the terms with the most votes. removefirstlist([H|T],T,H). %makeconjunction(CharsLists,CurrentList,ConjunctionList) :- conjunctionList is a list of ASCII codes corresponding %to the string specified by the proteins in ProteinsWithoutSeqSim conjoined by "and"s. CurrentList is an accumulator. makeandstring([H|T],CurrentList,ConjunctionList) :- length(T,L), L > 0, append(CurrentList,[44,32],X), append(X,H,Y), makeandstring(T,Y,ConjunctionList). makeandstring([H|T],CurrentList,ConjunctionList) :- length(T,L), L =:= 0, append(CurrentList,[32,97,110,100,32],X), append(X,H,Y), makeandstring(T,Y,ConjunctionList). makeandstring([],ConjunctionList,ConjunctionList). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% Code for selecting functional groups. %%%%%%%%%%%%%% %%%%%%%%%%%%% Last updated 9/2/04 %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% selectfunctionalgroups. This is the first top level goal %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %selectfunctionalgroups(GOIDs,FunctionalGroups) :- GOIDs is a list of the GO accesion numbers of the input %protein domains. FunctionalGroups is a list of the functional groups of those GOIDs, that is, a list of subgroups %such that the GOIDs in those subgroups form closely related groups in the GO molecular function hierarchy. %e.g. selectfunctionalgroups(['3','5','8','11','12','15','16','19','22','27','30'],FunctionalGroups). % FunctionalGroups = [['8','19'],['3','8','16','19'],['19','22'],['12','27'],['5','11','12','27'],['27','30'],['15','27','30']] ; %e.g. selectfunctionalgroups(['GO:0004794','GO:0004834','GO:0004124','GO:0008811','GO:0016407','GO:0030523','GO:0004149'],Groups). % Groups = [['GO:0030523','GO:0004149'],['GO:0016407','GO:0008811'],['GO:0008811','GO:0016407','GO:0030523','GO:0004149'],['GO:0004794','GO:0004834'],['GO:0004794','GO:0004834','GO:0004124'],['GO:0004794','GO:0004834','GO:0004124','GO:0008811','GO:0016407','GO:0030523','GO:0004149']] ; selectfunctionalgroups(GOIDs,FunctionalGroups) :- removeduplicates(GOIDs,[],GOIDsWODups), getpaths(GOIDsWODups,Paths), grouppaths(Paths,GroupedPaths), groupproteins(GroupedPaths,GOIDs,FunctionalGroups),!. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %getpaths(GOIDs,Paths) :- GOIDs is a list of the GO ID numbers of the input set of protein domains. %Paths is a list if lists, such that each list is a list of the GOIDs that is the path from each number %in GOIDs to the node in the molecular function hierarchy at a depth of 2. (We do not need the path to the %root since the root (Gene_Ontology), and the single node at level 1 (molecular_function) are too general %to be of interest. /* getpaths(['3','5','8','11','12','15','16','19','22','27','30'],Paths). Paths = [['6','14','30'],['5','12','27'],['6','13','27'],['6','14','27'],['4','9','22'],['3','8','19'],['4','9','19'],['3','7','16'],['6','15'],['5','12'],['5','11'],['3','8']] */ getpaths(GOIDs,Paths) :- auxgetpaths(GOIDs,[],Paths). %A given node in the list GOIDs may have more than one path to a 2nd level node or nodes. For this reason %we use the built-in predicate findall to return a list of all such paths, which are then appended to a list of all paths. auxgetpaths([H1|T1],TempList,Paths) :- findall(PathsForNode,getpathfornode(H1,PathsForNode),X), append(X,TempList,NewPaths), auxgetpaths(T1,NewPaths,Paths). auxgetpaths([],Paths,Paths). %getpathfornode(Node,Path) :- Path is a list of nodes forming a path from a node at depth 2 in hierarchy to the node. getpathfornode(Node,Path) :- path(Path), length(Path,Length), Length > 1, getlast(Path,Node). %getlast(List,Last) :- Last is the last member of List. getlast(List,Last) :- reverse(List,[Last|T]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %grouppaths(Paths,GroupedPaths) :- Paths is a list of lists: each list is a path. GroupedPaths is a %list of list of lists. Each list of lists is a list of those paths that start from the same GOID. (A 2nd %level node in the GO hierarchy.) %e.g. grouppaths([['6','14','30'],['5','12','27'],['6','13','27'],['6','14','27'],['4','9','22'],['3','8','19'],['4','9','19'],['3','7','16'],['6','15'],['5','12'],['5','11'],['3','8']],GroupedPaths). %?- GroupedPaths = [[['6','14','30'],['6','13','27'],['6','14','27'],['6','15']],[['5','12','27'],['5','12'],['5','11']],[['4','9','22'],['4','9','19']],[['3','8','19'],['3','7','16'],['3','8']]] ; grouppaths(Paths,GroupedPaths) :- auxgrouppaths(Paths,GroupedPaths). auxgrouppaths([H|T],[L1|L2]) :- getnextgroup(H,[H|T],L1,L3), auxgrouppaths(L3,L2). auxgrouppaths([],[]). /* %getnextgroup(Element,List,Sublist of list that consists of element, sublist of list that is not element). getnextgroup(H,[H|T1],[H|T2],T3) :- getnextgroup(H,T1,T2,T3). getnextgroup(H1,[H2|T1],T2,[H2|T3]) :- H1 \== H2, getnextgroup(H1,T1,T2,T3). getnextgroup(H,[],[],[]). */ %getnextgroup(List,List of lists,Sublist of list of lists that consists of lists starting with %elements that are the same as the first element of list, sublist of list of lists that start with %an element different from the element with which list starts.). getnextgroup([H1|T1],[[H1|T2]|T3],[[H1|T2]|T4],T5) :- getnextgroup([H1|T1],T3,T4,T5). getnextgroup([H1|T1],[[H2|T2]|T3],T4,[[H2|T2]|T5]) :- H1 \== H2, getnextgroup([H1|T1],T3,T4,T5). getnextgroup([H1|T1],[],[],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %This is the code for actually grouping the lists of paths into functional subgroups. %groupproteins(GroupsOfPaths,GOIDs,GroupsOfGOIDs) :- GroupsOfPaths is a list containing groups of paths of %GOID terms, where each group consists of paths which START with the SAME GOID number. It is, thus, a list of lists %of lists. (It should be the binding, GroupedPaths, from the clause grouppaths, see above.) GroupsOfGOIDs is %a list of groups of GOIDs that belong together as functional groupings. It is, thus, a list of lists. GOIDs is the %list of GOID numbers corresponding to the input protein domains being merged. %e.g. ?- groupproteins([[['6','14','30'],['6','13','27'],['6','14','27'],['6','15']],[['5','12','27'],['5','12'],['5','11']],[['4','9','22'],['4','9','19']],[['3','8','19'],['3','7','16'],['3','8']]],['3','5','8','11','12','15','16','19','22','27','30'],GroupsOfGOIDs). % GroupsOfGOIDs = [['8','19'],['3','8','16','19'],['19','22'],['12','27'],['5','11','12','27'],['27','30'],['15','27','30']] ; groupproteins(GroupsOfPaths,GOIDs,GroupsOfGOIDs) :- auxgroupproteins(GroupsOfPaths,GOIDs,[],GroupsWithDups), removeduplicates(GroupsWithDups,[],GroupsWODups), removesingletons(GroupsWODups,GroupsOfGOIDs). auxgroupproteins([H|T],GOIDs,Accumulator,GroupsOfGOIDs) :- getproteingroups(GOIDs,H,H,[],Groupings), append(Groupings,Accumulator,NewList), auxgroupproteins(T,GOIDs,NewList,GroupsOfGOIDs). auxgroupproteins([],GOIDs,GroupsOfGOIDs,GroupsOfGOIDs). %getproteingroups(GOIDs,Paths,PrevPaths,Accumulator,Groupings) :- PrevPaths are all the paths %in paths from the previous recusive call -- it's required for the case where not all the remaining paths %start from the same node. Paths is a list of all the paths that originally started from the same node, and %terminating with (some of) the nodes which are the GOIDs of the input set of proteins. Groupings is a list %of all the groupings that can be extracted from the nodes in the paths. It's a list of lists. %e.g. getproteingroups([3,5,8,11,12,15,16,19,22,27,30],[[3,8],[3,7,16],[3,8,19]],[[3,8],[3,7,16],[3,8,19]],[],Groupings). % Groupings = [[8,19],[8,19],[3,8,19,16],[3,8,19,16]] %e.g. getproteingroups(['3','5','8','11','12','15','16','19','22','27','30'],[['6','14','30'],['6','13','27'],['6','14','27'],['6','15']],[['6','14','30'],['6','13','27'],['6','14','27'],['6','15']],[],Groupings). % Groupings = [['27','30'],['15','27','30']] %e.g. getproteingroups(['3','5','8','11','12','15','16','19','22','27','30'],[['5','12','27'],['5','12'],['5','11']],[['5','12','27'],['5','12'],['5','11']],[],Groupings). % Groupings = [['27'],['12','27'],['5','11','12','27'],['5','11','12','27']] %e.g. getproteingroups(['3','5','8','11','12','15','16','19','22','27','30'],[['4','9','22'],['4','9','19']],[['4','9','22'],['4','9','19']],[],Groupings). % Groupings = [['19','22']] %Note that duplicates and singletons are removed by subsidary goals to the higher level goal groupproteins. %Case 1: All remaining paths start with the SAME node AND that node IS in the list of input nodes, GOIDs. %Action: Create a grouping from all the nodes in the paths that are in GOIDs. Then shorten paths, and call goal again. getproteingroups(GOIDs,Paths,PrevPaths,Accumulator,Groupings) :- samefirstmember(Paths), getfirstmember(Paths,First), member(First,GOIDs), creategrouping(Paths,GOIDs,Grouping), append([Grouping],Accumulator,NewList), deletefirst(Paths,ShorterPaths), getproteingroups(GOIDs,ShorterPaths,Paths,NewList,Groupings). %Case 2: All remaining paths start with the SAME node AND that node IS NOT in the list of input nodes, GOIDs. %Action: Don't create a grouping. Just shorten paths, and call goal again. getproteingroups(GOIDs,Paths,PrevPaths,Accumulator,Groupings) :- samefirstmember(Paths), getfirstmember(Paths,NewFirst), not member(NewFirst,GOIDs), deletefirst(Paths,ShorterPaths), getproteingroups(GOIDs,ShorterPaths,Paths,Accumulator,Groupings). %Case 3: NOT all remaining paths start with the SAME node AND PREVIOUS set of paths start with SAME node. %Actions: (a) Form a grouping of all nodes in those paths that are in GOIDs. %(b) Take each remaining path individually; group all nodes in it that are in GOIDs into a separate group. Then shorten paths, and call goal again. getproteingroups(GOIDs,Paths,PrevPaths,Accumulator,Groupings) :- not samefirstmember(Paths), samefirstmember(PrevPaths), creategrouping(PrevPaths,GOIDs,Grouping), append([Grouping],Accumulator,NewList), deletefirst(Paths,ShorterPaths), getfinalgroupings(Paths,GOIDs,[],FinalGroupings), append(FinalGroupings,NewList,AllGroupings), getproteingroups(GOIDs,ShorterPaths,Paths,AllGroupings,Groupings). %Case 4: NOT all remaining paths start with the SAME node AND PREVIOUS set of paths do NOT start with the same node. %Actions: (a) Using the previous set of paths we group them according to their firt nodes, and then look at these %groups of paths separately to seek functional groupings of nodes. %(b) Take each remaining path individually; group all nodes in it that are in GOIDs into a separate group. Then shorten paths, and call goal again. getproteingroups(GOIDs,Paths,PrevPaths,Accumulator,Groupings) :- not samefirstmember(Paths), not samefirstmember(PrevPaths), grouppaths(PrevPaths,GroupedPaths), getothergroupings(GroupedPaths,GOIDs,OtherGroupings), append(OtherGroupings,Accumulator,NewList), deletefirst(Paths,ShorterPaths), getfinalgroupings(Paths,GOIDs,[],FinalGroupings), append(FinalGroupings,NewList,AllGroupings), getproteingroups(GOIDs,ShorterPaths,Paths,AllGroupings,Groupings). %Case 5: Base case. There are no paths remaining because they have been shortened. Note: we are NOT recursing %over Paths, removing the head each time until we reach the end of the list. Rather, we are removing the head %of each list in Paths, and calling the same goal until there are no lists left in Paths, which is now the empty list. getproteingroups(GOIDs,[],PrevPaths,Groupings,Groupings). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %These are the helper clauses. %creategrouping(ListOfPaths,GOIDs,Grouping) :- ListOfPaths is a list of lists. Each list is a path starting from the %same node in the GO hierarchy. GOIDs is the list of accession numbers corresponding to each protein domain in the %input set. Grouping is a list of GOIDs that can be grouped together. This can be used to group the corresponding domains. %| ?- creategrouping([[4,9,16],[4,9,13,17],[4,22]],[3,5,8,15,16,17,22,24,25],Grouping). % Grouping = [22,17,16] ; %| ?- creategrouping([[5,10,11,12,19,22],[5,10,11,12,19,24],[5,10,11,12,25]],[3,5,8,15,16,17,22,24,25],Grouping). % Grouping = [5,25,24,22] ; creategrouping(ListOfPaths,GOIDs,Grouping) :- auxcreategrouping(ListOfPaths,GOIDs,[],GroupingWithDups), removeduplicates(GroupingWithDups,[],Grouping). auxcreategrouping([H|T],GOIDs,Accumulator,Grouping) :- getnodesfrompath(H,GOIDs,Nodes), append(Nodes,Accumulator,NewList), auxcreategrouping(T,GOIDs,NewList,Grouping). auxcreategrouping([],GOIDs,Grouping,Grouping). %removeduplicates(List,Accumulator,ListWithoutDupes) :- ListWithoutDupes is the list List, with all duplicates removed. %Accumulator should be the empty list when this predicate is called. %For example: removeduplicates([a,b,c,b,b,d,b,e],[],X). % ?- X = [a,b,c,d,e] %Case 1: Aleady in list, so don't add. removeduplicates([H|T],Accumulator,ListWODupes) :- member(H,Accumulator), removeduplicates(T,Accumulator,ListWODupes). %Case 2: Not in list, so add. removeduplicates([H|T],Accumulator,ListWODupes) :- not member(H,Accumulator), append(Accumulator,[H],NewList), removeduplicates(T,NewList,ListWODupes). removeduplicates([],ListWODupes,ListWODupes). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %getnodesfrompath(Path,GOIDs,Nodes) :- Nodes is a list of nodes from the list Path that occur in %the list GOIDs. The latter list is the list of GOID numbers corresponding to the protein domains to be merged. %e.g. getnodesfrompath([5,10,11,12,19,22],[3,5,8,15,16,17,22,24,25],Nodes). % ?- Nodes = [5,22] %Node in path is in list of GOIDs. getnodesfrompath([H1|T1],GOIDs,[H1|T2]) :- member(H1,GOIDs), getnodesfrompath(T1,GOIDs,T2). %Node in path is not in list of GOIDs. getnodesfrompath([H1|T1],GOIDs,Nodes) :- not member(H1,GOIDs), getnodesfrompath(T1,GOIDs,Nodes). %Base case. getnodesfrompath([],GOIDs,[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %getfinalgroupings(Paths,GOIDs,Accumulator,Groupings) :- Groupings is a list of groupings of nodes (i.e. a list of lists) %such that each grouping consists of those nodes in a single path in Paths that are in list GOIDs, provided that grouping is of size > 1. %This is used is cases 3 and 4 of the goal getproteingroups, after the paths have split, so that their first nodes are no longer the same. From that %point on, any groupings, concerning JUST THE NODES IN THESE PATHS, will all be amongst nodes WITHIN each path. %e.g. getfinalgroupings([[11],[12],[12,27]],[3,5,8,11,12,15,16,19,22,27,30],[],Groupings). % Groupings = [[12,27]] getfinalgroupings([Path|T],GOIDs,Accumulator,Groupings) :- getnodesfrompath(Path,GOIDs,Grouping), length(Grouping,Length), Length > 1, append([Grouping],Accumulator,NewList), getfinalgroupings(T,GOIDs,NewList,Groupings). getfinalgroupings([Path|T],GOIDs,Accumulator,Groupings) :- getnodesfrompath(Path,GOIDs,Grouping), length(Grouping,Length), Length < 2, getfinalgroupings(T,GOIDs,Accumulator,Groupings). getfinalgroupings([],GOIDs,Groupings,Groupings). %Used in Case 4: first members of remaining paths are not the same, nor are the previous first members the same. Here we %seek to divide the paths such that thy are grouped according to the first members of the previous paths. Then within %these new groupings of paths, we seek other groupings of nodes. %getothergroupings(GroupedPaths,GOIDs,OtherGroupings) :- GroupedPaths is a list of groups of paths, where in those groups %each path starts with the same node. OtherGroupings is a list of groupings, such that those groupings are all the nodes %from a groups of paths that are in the input list of GOIDs. %e.g. getothergroupings([[[11,12,19,22],[11,12,19,24],[11,12,25]],[[18,26],[18,27]]],[3,5,8,15,16,17,22,24,25,26,27],Groupings). % Groupings = [[25,24,22],[27,26]] ; %Case 1: More than one path starts with a given node. We want to see if there's a grouping. getothergroupings([H|T1],GOIDs,[Grouping|T2]) :- length(H,Length), Length > 1, creategrouping(H,GOIDs,Grouping), getothergroupings(T1,GOIDs,T2). %Case 2: Only one path starts with a given node. We don't want to see if there's a grouping. getothergroupings([H|T1],GOIDs,Groupings) :- length(H,Length), Length < 2, getothergroupings(T1,GOIDs,Groupings). getothergroupings([],GOIDs,[]). %The central clause, getproteingroups, reaches its base case not by recursing over the %lists of paths, but by shortening those paths by removing the first element of each remaining path. %When there are no more paths, the recursion stops. %deletefirst(Paths,ShorterPaths) :- ShorterPaths is a list of paths from Paths, whith the first member of each path removed. %e.g. | ?- deletefirst([[3,8],[3,8,15],[3,8,16]],X). % X = [[8],[8,15],[8,16]] ; %e.g. | ?- deletefirst([[14],[15],[16]],X). % X = [] %List has more than one member deletefirst([[H|T1]|T2],[T1|T3]) :- length(T1,Length), Length > 0, deletefirst(T2,T3). %List has just one member deletefirst([[H|T1]|T2],T3) :- length(T1,Length), Length =:= 0, deletefirst(T2,T3). deletefirst([],[]). %samefirstmember(Paths) :- succeeds if all the paths in the list Paths start with the same first member. %Paths may be empty list. samefirstmember(Paths) :- length(Paths,Length), Length =:= 0. samefirstmember([[H1|T1]|T2]) :- length([[H1|T1]|T2],Length), Length > 0, auxsamefirstmember(H1,T2). auxsamefirstmember(First,[[First|T1]|T2]) :- auxsamefirstmember(First,T2). auxsamefirstmember(First,[]). %getfirstmember(Paths,First) :- First is the common first member of the paths in Paths. %Path used must have more than one member. %e.g. | ?- getfirstmember([[8],[9],[10,8,16]],X). % X = 10 ; /* getfirstmember([[H1|T1]|T2],H1) :- length(T1,Length), Length > 0. getfirstmember([[H1|T1]|T2],First) :- length(T1,Length), Length =:= 0, getfirstmember(T2,First). */ getfirstmember([[H1|T1]|T2],H1). %removesingletons(Groups,GroupsWithoutSingletons) :- GroupsWithoutSingletons is all the groups from list Groups that %are not singletons. removesingletons([H|T1],[H|T2]) :- length(H,Length), Length > 1, removesingletons(T1,T2). removesingletons([H|T1],GroupsWithoutSingletons) :- length(H,Length), Length =:= 1, removesingletons(T1,GroupsWithoutSingletons). removesingletons([],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% selectproteingroups. This is the second top level goal %%%%%%%%%%%%%% %%%%%%%%%%%%% This goal is called AFTER selectfunctionalgroups, which %%%%%%%%%%%%%% %%%%%%%%%%%%% provides the binding for FunctionalGroups. %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %selectproteingroups(Proteins,GOIDs,FunctionalGroups,SelectedProteins) :- SelectedProteins (list of lists) is a list of %subsets of protein domains, selected from the input set Proteins (list), that are judged to belong together as a %functional subgroup. GOIDs (list) are the GO ID numbers of the input domains, and FunctionalGroups (list of lists) is a list %of functional subgroups from those GO IDs. Note that since more than one protein domain canshare the same GOIDs, we have %to make sure that for each GOID in FunctionalGroups, ALL proteins that have that ID are added to the groupings of proteins. %e.g. selectproteingroups([a,b,c,d,e,f,g,h],[1,2,3,1,5,3,1,4],[[1,2,3],[4,5,2,1],[2,3]],SelectedProteins). % SelectedProteins = [[c,f,b,a,d,g],[a,d,g,b,e,h],[c,f,b]] selectproteingroups(Proteins,GOIDs,FunctionalGroups,SelectedProteins) :- combine(Proteins,GOIDs,ProtGOIDs), swapnamesforIDs(ProtGOIDs,FunctionalGroups,SelectedProteins). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Helper goals. %combine(List1,List2,ListOfPairs) :- combines two lists of equal length into a single list of pairs. %e.g. | ?- combine([1,2,3,4,5],[a,b,c,d,e],X). % X = [[1,a],[2,b],[3,c],[4,d],[5,e]] combine([H1|T1],[H2|T2],[[H1,H2]|T3]) :- combine(T1,T2,T3). combine([],[],[]). %swapnamesforIDs(ProtGOIDs,FunctionalGroups,SelectedProteins) :- FunctionalGroups is a list of functionally grouped %GOID numbers (i.e. a list of lists). This goal succeeds by producing the equivalent set of groupings, but swapping the names of protein domains %for those ID numbers. %e.g. swapnamesforIDs([[a,1],[b,2],[c,1],[d,1],[e,3],[f,2],[g,2],[h,3],[i,2],[j,4]],[[1,2,3],[4,3,2,1],[4,3]],ProtList). % ProtList = [[e,h,b,f,g,i,a,c,d],[a,c,d,b,f,g,i,e,h,j],[e,h,j]] swapnamesforIDs(ProtGOIDs,[GOIDList|T1],[ProtList|T2]) :- swaplists(ProtGOIDs,GOIDList,[],ProtList), swapnamesforIDs(ProtGOIDs,T1,T2). swapnamesforIDs(ProtGOIDs,[],[]). %swaplists(ProtGOIDs,GOIDList,Accumulator,ProtList) :- ProtGOIDs is a list of name-ID pairs. We loop over this checking %the ID with the ID in the list GOIDList, and if there's a match, we add the corresponding name to the list of %proteins, ProtList. %e.g. swaplists([[a,1],[b,2],[c,1],[d,1],[e,3],[f,2],[g,2],[h,3],[i,2],[j,4]],[2,4],[],ProtList). %ProtList = [j,b,f,g,i] swaplists(ProtGOIDs,[ID|T1],Accumulator,ProtList) :- findmatch(ProtGOIDs,ID,Names), append(Names,Accumulator,NewList), swaplists(ProtGOIDs,T1,NewList,ProtList). swaplists(ProtGOIDs,[],ProtList,ProtList). %findmatch((ProtGOIDs,ID,Names) :- looks through list of name-ID pairs (ProtGOIDs) and %finds all names for ID. Names is thus a list. ProtGOIDs is a list of pairs. %e.g. findmatch([[a,1],[b,2],[c,1],[d,1],[e,3]],1,X). % X = [a,c,d] %findmatch([[a,1],[b,1],[c,2],[d,3],[e,4]],5,X). %no %Match. Add name to list and look for further matches. findmatch([[Name,ID]|T1],ID,[Name|T2]) :- findmatch(T1,ID,T2). %No match, try next pair in list. findmatch([[OtherName,OtherID]|T],ID,Names) :- OtherID \== ID, findmatch(T,ID,Names). %Base findmatch([],ID,[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% expandfunctionalgroups. This is the THIRD top level goal %%%%%%%%%%%%%% %%%%%%%%%%%%% This goal is called AFTER selectproteingroups, which %%%%%%%%%%%%%% %%%%%%%%%%%%% provides the binding for SelectedProteins. %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %We have a slight problem to overcome. In oreder to find the least upper bound of each %functional grouping, the goal semanticgeneralization/3 requires a matching GOID (which may in %fact be "null") for each protein name. At this point, we have a list of lists of protein names %(each list being a subgroup that whose LUB is to be found), anda list of list of GOIDs (each %list being the GOIDs of the proteins named in the other lists). However, though each list contains %the same number of lists, the lists themselves may be of unequal lengths. This is because the lists %of GOIDs contain NO DUPLICATES, yet very many of the proteins names in the other lists will share %the same GOIDs. This is a problem because the goal semanticgeneralization/3 requires those lists %of names and lists of GOIDs to be of the same length. So ...... %expandfunctionalgroupings(Proteins,GOIDs,SelectedProteins,ExpandedFunctionalGroups) :- SelectedProteins is a list %of lists, where each lists contains the names of proteins forming a functional group whose LUB is to be found. %ExpandedFunctionalGroups is also a list of lists, where each list contains the GOID of the protein named in the %equivalent list in SelectedProteins. expandfunctionalgroupings(Proteins,GOIDs,SelectedProteins,ExpandedFunctionalGroups) :- combine(Proteins,GOIDs,ProtGOIDs), expandlists(SelectedProteins,ProtGOIDs,ExpandedFunctionalGroups). %e.g. expandlists([[a,b,c,d],[a,c],[c,d]],[[a,1],[b,1],[c,2],[d,3]],ExpandedFunctionalGroups). % ExpandedFunctionalGroups = [[1,1,2,3],[1,2],[2,3]] expandlists([ProtList|T1],ProtGOIDs,[GOIDList|T2]) :- auxexpandlist(ProtList,ProtGOIDs,GOIDList), expandlists(T1,ProtGOIDs,T2). expandlists([],ProtGOIDs,[]). %e.g. auxexpandlist([a,b,c,d],[[a,1],[b,1],[c,2],[d,3]],IDList). % IDList = [1,1,2,3] auxexpandlist([Name|T1],ProtGOIDs,[ID|T2]) :- findID(Name,ProtGOIDs,ID), auxexpandlist(T1,ProtGOIDs,T2). auxexpandlist([],ProtGOIDs,[]). %findID(Name,ProtGOIDs,ID) :- Id is the GOID number for the protein domain Name, as given in the list %of name/ID pairs, PRotGOIDs. %e.g. findID(c,[[a,1],[b,1],[c,2],[d,3]],ID). % ID = 2 %Case 1: Found match. findID(Name,[[Name,ID]|T],ID). %Case 2: No match, try next pair. findID(Name,[[OtherName,WrongID]|T],ID) :- Name \== OtherName, findID(Name,T,ID). %Case 3: End of list, fail. findID(Name,[],ID) :- fail. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% getleastupperbounds. This is the FOURTH top level goal %%%%%%%%%%%%%% %%%%%%%%%%%%% This goal is called AFTER expandfunctionalgroups, which %%%%%%%%%%%%%% %%%%%%%%%%%%% provides the binding for FunctionalGroups. %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %The third top level goal. This is the condition that follows selectproteingroups/4 %getleastupperbounds(SelectedProteins,FunctionalGroups,Commonfunctions) :- CommonFunctions is the list %of least upper bounds or semantic generalizations of the subgroups of protein domains in SelectedProteins. %FunctionalGroups is the matching set of grouped GOID terms for those domains. Essentially all this %predicate does is loop over the first two lists calling the goal semanticgeneralization. Since there may %be more than one such LUB for a group of proteins (the GO hierarchy being a graph, not a tree), CommonFunctions %is a list of lists, those most of the list in the list will have only one member. getleastupperbounds([Proteins|T1],[GOIDs|T2],[LeastUpperBounds|T3]) :- semanticgeneralization(Proteins,GOIDs,LeastUpperBounds),!, getleastupperbounds(T1,T2,T3). getleastupperbounds([],[],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% getkeywordgroups. This is the FIFTH top level goal %%%%%%%%%%%%%% %%%%%%%%%%%%% This goal is called AFTER getleastupperbounds, which %%%%%%%%%%%%%% %%%%%%%%%%%%% provides the binding for CommonFunctions. %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %The fourth top-level goal. We need to get the list of key words for each functional grouping. %getkeywordgroups(CommonFunctions,KeywordGroups) :- KeywordGroups is the list of keywords for each %common function in list CommonFunctions. It is, then, a list of lists. Note that since there may %be more than one LUB for a given protein grouping (since hierarchy is a graph), then CommonFunctions %is a list of lists. getkeywordgroups([LUBs|T1],[Keywords|T2]) :- findancestors(LUBs,Ancestors), getkeywords(Ancestors,Keywords), getkeywordgroups(T1,T2). getkeywordgroups([],[]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%% getnumberofunctionalgroups. This is the SIXTH top level %%%%%%%%%%%%%% %%%%%%%%%%%%% goal. This goal is called AFTER getkeywordgroups. %%%%%%%%%%%%%% %%%%%%%%%%%%% -- i.e. it's a condition name for a fusion rule. %%%%%%%%%%%%%% %%%%%%%%%%%%% %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %The fifth top-level goal. We need to know the number of functional groupings so %that we can know how many subreports to include in the merged report. getnumberoffunctionalgroups(SelectedProteins,Number) :- length(SelectedProteins,Number). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Some paths for testing. path(['3']). path(['3','7']). path(['3','8']). path(['3','7','16']). path(['3','7','17']). path(['3','8','18']). path(['3','8','19']). path(['4']). path(['4','9']). path(['4','9','19']). path(['4','9','20']). path(['4','9','21']). path(['4','9','22']). path(['5']). path(['5','10']). path(['5','11']). path(['5','12']). path(['5','10','23']). path(['5','11','24']). path(['5','11','25']). path(['5','12','26']). path(['5','12','27']). path(['6']). path(['6','13']). path(['6','14']). path(['6','15']). path(['6','13','27']). path(['6','14','27']). path(['6','14','28']). path(['6','14','29']). path(['6','14','30']). %Go paths. path(['GO:0003824','GO:0016829']). path(['GO:0003824','GO:0016829','GO:0016835']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016836']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016836','GO:0004794']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016836','GO:0004122']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016836','GO:0004834']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016839']). path(['GO:0003824','GO:0016829','GO:0016835','GO:0016839','GO:0004124']). path(['GO:0003824','GO:0016491']). path(['GO:0003824','GO:0016491','GO:0016705']). path(['GO:0003824','GO:0016491','GO:0016705','GO:0016709']). path(['GO:0003824','GO:0016491','GO:0016705','GO:0016709','GO:0004517']). path(['GO:0003824','GO:0016740']). path(['GO:0003824','GO:0016740','GO:0016746']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016407']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016407','GO:0016413']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016407','GO:0016413','GO:0008811']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0008374']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0008374','GO:0016413']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0008374','GO:0016413','GO:0008811']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016417']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016417','GO:0030523']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016417','GO:0016751']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016417','GO:0016751','GO:0004149']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016748']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016748','GO:0016751']). path(['GO:0003824','GO:0016740','GO:0016746','GO:0016747','GO:0008415','GO:0016748','GO:0016751','GO:0004149']). %%%%%%%%%%% %Test code: /* %First condition. selectfunctionalgroups(['GO:0008811','GO:0030523','GO:0004149'],FunctionalGroups). FunctionalGroups = [['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149']] %Second Condition. selectproteingroups(['2cla00','1dpd00','1c4tA0'],['GO:0008811','GO:0030523','GO:0004149'],[['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149']],SelectedProteins). SelectedProteins = [['1dpd00','1c4tA0'],['2cla00','1dpd00','1c4tA0']] %Third Condition. getleastupperbounds([['1dpd00','1c4tA0'],['2cla00','1dpd00','1c4tA0']],[['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149']],CommonFunctions). CommonFunctions = [['GO:0016417'],['GO:0008415']] %Fourth Condition. getkeywordgroups([['GO:0016417'],['GO:0008415']],KeywordGroups). KeywordGroups = [[' transferring acyl groups',' transferring groups other than amino-acyl groups','Gene_Ontology','S-acyltransferase activity','acyltransferase activity','catalytic activity',molecular_function,'transferase activity'],[' transferring acyl groups',' transferring groups other than amino-acyl groups','Gene_Ontology','acyltransferase activity','catalytic activity',molecular_function,'transferase activity']] ; %Fifth Condition. getnumberoffunctionalgroups([['1dpd00','1c4tA0'],['2cla00','1dpd00','1c4tA0']] ,Number). Number = 2 %More tests of first condn. | ?- selectfunctionalgroups(['GO:0008811','GO:0004517','GO:0030523','GO:0004149'],FunctionalGroups). FunctionalGroups = [['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149'],['GO:0008811','GO:0004517','GO:0030523','GO:0004149']] | ?- selectfunctionalgroups(['GO:0016709','GO:0008811','GO:0004517','GO:0030523','GO:0004149'],FunctionalGroups). FunctionalGroups = [['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149'],['GO:0016709','GO:0004517'],['GO:0016709','GO:0008811','GO:0004517','GO:0030523','GO:0004149']] | ?- selectfunctionalgroups(['GO:0016709','GO:0008811','GO:0004124','GO:0004517','GO:0030523','GO:0004149','GO:0004122'],FunctionalGroups). FunctionalGroups = [['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149'],['GO:0016709','GO:0004517'],['GO:0004124','GO:0004122'],['GO:0016709','GO:0008811','GO:0004124','GO:0004517','GO:0030523','GO:0004149','GO:0004122']] | ?- selectfunctionalgroups(['GO:0016709','GO:0004834','GO:0008811','GO:0004124','GO:0004517','GO:0030523','GO:0004149','GO:0004122'],FunctionalGroups). FunctionalGroups = [['GO:0030523','GO:0004149'],['GO:0008811','GO:0030523','GO:0004149'],['GO:0004834','GO:0004122'],['GO:0016709','GO:0004517'],['GO:0004834','GO:0004124','GO:0004122'],['GO:0016709','GO:0004834','GO:0008811','GO:0004124','GO:0004517','GO:0030523','GO:0004149','GO:0004122']] */