1

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.

false
  • 10,264
  • 13
  • 101
  • 209
Zoli
  • 23
  • 3
  • I'm voting to close this question as off-topic because SO is not a code-writing service. – Marco Bonelli Apr 19 '17 at 10:23
  • Take a quick read through SWI Prolog's library of predicates for string processing. Specifically, there are predicates that break it down into a list of characters. You should easily find something to give you an idea how to get started. Also, you wouldn't want to end when the "head is 'a'` but rather when the last character in the list is `'a'`. – lurker Apr 19 '17 at 10:49
  • 1
    Could you say what `avegu` means? – false Apr 19 '17 at 14:04

2 Answers2

3

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.
false
  • 10,264
  • 13
  • 101
  • 209
  • 1
    This is a much better answer, I guess I misunderstood the question, but I really could not know what "string" means, I don't know if there is easy way to ever know what people mean when they say "string" in Prolog. –  Apr 20 '17 at 08:32
  • 1
    @User9213: OP spoke about a "character list (string)". Many requests for strings actually mean a list of characters or character codes. – false Apr 20 '17 at 11:02
2

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.