0
votes

I am trying to create a prolog program that accept input "i love you" as a string and then output

"i love you"
"i love yo"
"i love y"
"i love "
"i love"
"i lov"
"i lo"
"i l"
"i "
"i"

I am currently using SWI-Prolog, and the code I have is the following.

sublist(S, L) :-
  append(_, L2, L),
  append(S, _, L2).

contains(A, B) :-
  atom(A),
  name(A, AA),
  contains(AA, B).

contains(A, B) :-
  sublist(B, A),
  B \= [].

I use the following to execute the code :

?- forall(contains('i love you',X),writef("%s\n",[X])).

The following is the output generated exactly as shown.

i
i 
i l
i lo
i lov
i love
i love 
i love y
i love yo
i love you

 l
 lo
 lov
 love
 love 
 love y
 love yo
 love you
l
lo
lov
love
love 
love y
love yo
love you
o
ov
ove
ove 
ove y
ove yo
ove you
v
ve
ve 
ve y
ve yo
ve you
e
e 
e y
e yo
e you

 y
 yo
 you
y
yo
you
o
ou
u

I appreciate any and all help. Thanks a lot in advance.

2

2 Answers

1
votes

I dont fully understand your request (what do you mean with that accept input "i love you" as a string ?) but you don't really need a program to produce that output:

?- forall(append(_, [F|S], "I love you"), format('"~s"~n', [[F|S]])).
"I love you"
" love you"
"love you"
"ove you"
"ve you"
"e you"
" you"
"you"
"ou"
"u"
true.

the second argument of append/3 has been 'patterned' to be at least of length 1, to avoid the last empty string that would result otherwise.

edit the answer so far it's wrong: I didn't noticed that it shows the tail! Here is a debugged procedure, but not acting as a generator:

pheader([X]) :-
    format('~s~n', [[X]]), !.
pheader(L) :-
    format('~s~n', [L]),
    L = [_|Xs],
    pheader(Xs).

yields

?- pheader("i love you").
"i love you"
" love you"
"love you"
"ove you"
"ve you"
"e you"
" you"
"you"
"ou"
"u"
true.

then you need a 'program' to do it, at last!

edit to regain the initial behaviour (header generator), here a 2 argument procedure

pheader([X|Xs], [X|Xs]).
pheader([_|Xs], R) :-
    pheader(Xs, R).

yields, at last, the desidered output:

?- forall(pheader("i love you",X),format('"~s"~n', [X])).
"i love you"
" love you"
"love you"
"ove you"
"ve you"
"e you"
" you"
"you"
"ou"
"u"
true.
0
votes

To remove the last element of a list, you can use append(WithoutLast, [Last], List):

foo([]) :- !.
foo(S) :- format('"~s"~n', [S]), append(S1, [_Last], S), !, foo(S1).

?- foo("i love you").
"i love you"
"i love yo"
"i love y"
"i love "
"i love"
"i lov"
"i lo"
"i l"
"i "
"i"
true.

If you don't want it to be deterministic you can remove the cuts.