user840718
user840718

Reputation: 1611

List of lists in Prolog

I have a problem with list of lists in Prolog. For example, I have these facts:

fact(1, 'hello').
fact(2,  'boy').
fact(3, 'hello').
fact(4, 'girl').

and a list made of pairs like (Character, Id):

list([b, 1, b, 2, g, 3, g, 4]).

my goal is to return a list of lists like this:

newList(['hello', boy'], ['hello', 'girl']).

EDIT: The first list have to be split in more lists that share the same Character

list([b, 1, b, 2], [g, 3, g, 4]).

then, should be removed the Character

list([1, 2], [3, 4]).

and substitute the id with the corresponding atom like this:

list(['hello', 'boy'], ['hello', 'girl']).

Upvotes: 0

Views: 206

Answers (2)

CapelliC
CapelliC

Reputation: 60014

Well, here is a plain Prolog definition

list([], []).
list([S|R], [L|T]) :-
    capture(S, [S|R], L, Q),
    list(Q, T).

capture(S, [S,I|R], [N|Ns], Q) :-
    !, fact(I, N),
    capture(S, R, Ns, Q).
capture(_, Q, [], Q).

note: the cut is required for correctness of the procedure. It yields

?- list([b, 1, b, 2, g, 3, g, 4], R).
R = [[hello, boy], [hello, girl]].

Upvotes: 1

user1812457
user1812457

Reputation:

A weird question altogether. If you cared to give some context, you might get a more meaningful answer about how to do things in Prolog, in general.

Anyway:

First, if this is indeed a list of pairs, represent it as such:

char_id([b-1, b-2, g-3, g-4]).

If you want to do it programatically,

flat_to_pairs([], []).
flat_to_pairs([A,B|Flat], [A-B|Pairs]) :- flat_to_pairs(Flat, Pairs).

Then, you can use:

?- group_pairs_by_key([b-1, b-2, g-3, g-4], G).
G = [b-[1, 2], g-[3, 4]].

you can then map the IDs to the corresponding words:

collect_words([], []).
collect_words([C-IDs|ID_Groups], [C-Words|Word_Groups]) :-
    maplist(fact, IDs, Words),
    collect_words(ID_Groups, Word_Groups).

As a bonus, your words are marked with the initial character.

But as I said this all feels wrong on many levels.

Upvotes: 5

Related Questions