i have this fact and rules in prolog->
amino(a,ala,alanine,[gca,gcc,gcg,gct]).
amino(b,asx,asparagine,[aac,aat]).
amino(c,cys,cysteine,[tgc,tgt]).
amino(A,B,C,[H|T]):-
amino(A,B,C,[H|T]),
amino(A,B,C,T).
what im trying to do is to search for the name, single letter code and 3 letter code of the amino acid im trying to find from a given codon (the list).
when i query
?-amino(A,B,C,[tgc|_]).
it gives
A = c
B = cys
C = cysteine
so thats fine because tgc is the head of the list. but when i query
?-amino(A,B,C,[gct|_]).
it doesnt give anything. What im trying to do is to make prolog search for the codon in the list in the facts and print out everything in the fact (except the other codons) so im trying to make a recursion rule that would retrieve the whole fact from the query that provides an element in the tail of the list
As said in the comments, you have a case of left-recursion in amino.
As suggested, you should use memberchk with a different predicate:
amino_codon([A,B,C],Codon) :-
amino(A,B,C,L),
memberchk(Codon,L).
(Wrapping results in a list is optional).
However, the correct version of your approach would be:
amino_codon(A,B,C,L):- amino(A,B,C,L),!.
amino_codon(A,B,C,L):- amino_codon(A,B,C,[_|L]).
That way, either your query is matched by a fact, or you try to find a match with sublist T.
If you really wanted to have only one predicate, you would do as follows:
amino(a,ala,alanine,[gca,gcc,gcg,gct]):-!.
amino(b,asx,asparagine,[aac,aat]):-!.
amino(c,cys,cysteine,[tgc,tgt]):-!.
amino(A,B,C,T) :- amino(A,B,C,[_|T]).
Cuts were added because you are only interested to find one match.
Edit: sorry, there was an error in the above clauses, this is corrected now.
About cuts: if we don't add cuts, then the following happens.
Imagine you are trying to match amino(A,B,C,[gcc|_]) after you defined amino with the 4 clauses above (except without cuts):
amino(A,B,C,[gcg|_]), let's try to find a clause where amino(A,B,C,L) matches, such that the tail of L is T.L being [gca|T] and T being [gcc|_].L and T with other clauses, which will call recursively the 4rd clause until exhaustion of all possible choices.
You don't have multiple solutions here, and even if you had, you are only interested in returning one.If you left your predicates without cuts, the calling predicate would have to call once(amino(...)), or use a cut itself. Note that it might be desirable to leave this kind of decision to the caller and not explicitely add useless cuts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With