Reputation: 23
I received a task to write a Prolog program which can list all of those 'substrings' of a 'string', whose end with an 'a' character and length is at least two character.
For example:
?- avegu("baka", R).
R = "ba";
R = "baka";
R = "aka";
R = "ka";
false.
My idea is that I should split the given character list (string) to [Head|Tail] and call it recursively. When Head is 'a', returns the substring which I iterated over, then continue this until the end of the list. I don't know how to implement this idea.
Upvotes: 1
Views: 224
Reputation: 10122
You are touching here some issues.
First, you want that string is represented by a list of characters. The easiest way to get this is to use the directive
:- set_prolog_flag(double_quotes, chars).
Note that single characters do not need any extra quoting! Thus
?- "abc" = [A|BC].
A = a, BC = [b,c].
Then, it's all easy using a dcg:,
avegu(String, SubstringA) :-
Substring = [_|_],
phrase( ( ..., seq(Substring), "a", ... ), String),
phrase( ( seq(Substring), "a" ), SubstringA).
... --> [] | [_], ... .
seq([]) --> [].
seq([E|Es]) -->
[E],
seq(Es).
?- avegu("baka", R).
R = [b,a]
; R = [b,a,k,a]
; R = [a,k,a]
; R = [k,a]
; false.
See this answer for how to use double quotes for answers, which gives:
?- avegu("baka", R).
R = "ba"
; R = "baka"
; R = "aka"
; R = "ka"
; false.
Upvotes: 3
Reputation:
If I use atoms and not strings then I can use atom_length/2
and sub_atom/5
but there are the same for "string" if you use SWI.
babakaakaka(X, Sub) :-
atom_length(X, Len),
sub_atom(X, _, Sub_len, _, Sub),
between(2, Len, Sub_len),
sub_atom(Sub, _, 1, 0, a).
and then I write:
?- babakaakaka(baka, X).
X = ba ;
X = baka ;
X = aka ;
X = ka ;
false.
Upvotes: 2