Zoli
Zoli

Reputation: 23

All substring with 'a' character at the end

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

Answers (2)

false
false

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 :,

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

user7473772
user7473772

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

Related Questions