I've wrapped my mind a lot and couldn't figure it out. Is it possible to make a script that with backtrack generates lists in this format:
[a]
[a,b]
[a,b,a]
[a,b,a,b]
...
I've made one that generates two elements at a time but my head started to hurt trying to make one that generates "a" and the next time "b" and the next "a" and so on.
Here is the script for two elements at a time:
ab([a]).
ab([b,a|T]):-ab([a|T]).
ab([a,b|T]):-ab([b|T]).
Because of the problems of negation-as-failure, negation in Prolog is represented in modern Prolog interpreters using the symbol \+ , which is supposed to be a mnemonic for not provable with the \ standing for not and the + for provable.
symbol represents the cut . You can read more about cut here. Also, an example in prolog can be found here.
When you call copy , it works its way down to the base case, where it sets R to an empty list. Then, as it works back up, it keeps appending the head H of known list [H|T1] to the beginning of variable list [H|T2] . It does that until the original case is reached, at which point R contains a full copy of L .
The pipe operator in prolog returns one or more atomic Heads and a Tail list. ?- [a,b,c] = [a,b|[c]].
When describing lists, always consider using DCG notation.
This makes it very convenient to focus an the essence of what you want to describe, without so many additional variables and arguments.
For example, consider:
abs --> [a], abs_rest. abs_rest --> []. abs_rest --> [b], ( [] | abs ).
Sample query and answer:
?- phrase(abs, ABs). ABs = [a] ; ABs = [a, b] ; ABs = [a, b, a] ; ABs = [a, b, a, b] ; ABs = [a, b, a, b, a] ; ABs = [a, b, a, b, a, b] .
See dcg for more information about this convenient formalism!
I agree with @mat that one should use dcg when possible for these type of problems.
Here is a different set of rules.
abs --> [a].
abs --> [a,b].
abs --> [a,b], abs.
?- phrase(abs, Ls).
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a, b, a]
Interestingly those rules started from this variation
abs2 --> [].
abs2 --> [a].
abs2 --> [a,b], abs2.
?- phrase(abs2, Ls).
Ls = [] ;
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b]
which is one of the exercises from Using Definite Clause Grammars in SWI-Prolog
If you prefer not to use DCG, then I agree with @mat and suggest that you use listing/1
to see the DCG in standard Prolog syntax.
listing(abs).
abs([a|A], A).
abs([a, b|A], A).
abs([a, b|A], B) :-
abs(A, B).
listing(abs2).
abs2(A, A).
abs2([a|A], A).
abs2([a, b|A], B) :-
abs2(A, B).
As normal Prolog rules they can be used as such:
abs(X,[]).
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b, a]
abs2(X,[]).
X = [] ;
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b]
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