Reputation: 1124
I'm learning Prolog and I need idea how to convert a list of strings:
['f(a,45)', 'f(b,13)', 'f(c,12)']
into a list of pairs that looks like this:
[[45,'a'],[13,'b'],[12,'c']]
Upvotes: 0
Views: 532
Reputation: 5615
Alternatively, you can use this code :
convert :-
L = ["f(a,45)", "f(b,13)", "f(c,12)"],
maplist(extract_args,L, LA),
writeln(LA).
extract_args(S, [A1,A2]) :-
string_to_atom(S, A),
term_to_atom(T, A),
T =..[_, A2, A1].
If you have atoms, just use term_to_atom/2 in extract_args/2.
Upvotes: 0
Reputation: 60004
That's a list of atoms, not strings. Strings in Prolog are usually list of character codes, expressed like
["f(a,45)", "f(b,13)", "f(c,12)"]
Anyway, apply a conversion to each element with a recursive function:
convert([], []).
convert([Atom|Atoms], [Pair|Pairs]) :-
convert_element(Atom, Pair),
convert(Atoms, Pairs).
Instead of recursion you could use maplist/3 in this way:
convert(As, Ps) :- maplist(convert_element, As, Ps).
To convert an element, you need a parser. DCGs are convenient:
convert_element(Atom, [N, A]) :-
atom_codes(Atom, Codes),
phrase(("f(", atomc(Ac), ",", numc(Nc), ")"), Codes, []),
atom_codes(A, Ac),
number_codes(N, Nc).
atomc(A) --> ([C], {is_lowerc(C)}, atomc(Cs), {A = [C|Cs]}) ; {A = []}.
numc(N) --> ([C], {is_numc(C)}, numc(Cs), {N = [C|Cs]}) ; {N = []}.
is_lowerc(C) :- C @>= 0'a, C @=< 0'z.
is_numc(C) :- C @>= 0'0, C @=< 0'9.
test:
?- convert(['f(a,45)', 'f(b,13)', 'f(c,12)'],L).
L = [[45, a], [13, b], [12, c]] .
atomc//1 & numc//1 are expressed in a compact way, but are very simple recursive pattern matching procedures, i.e. atomc//1 could be
atomc([C|Cs]) --> [C], {is_lowerc(C)}, !, atomc(Cs).
atomc([]) --> [].
Upvotes: 1