move(Move) --> ["move", Move], { format("__ ~w", Move) }.
moves(Moves) --> ["moves"], Moves, { length(Moves, 2), format("__ ~w", Moves) }.
% this works as expected.
hello :- split_string("move ten", " ", "", Ls), phrase(move(_), Ls).
% this throws arguments error, I want to capture the list [one, two, three].
hello2 :- split_string("moves one two three", " ", "", Ls), phrase(moves(_), Ls).
% finally I want this to work without split_string debacle.
hello3 :- phrase(move(_), "move ten").
% note that it also has to work from strings read from stdin.
hello4 :-
read_line_to_string(user_input, L),
phrase(move(_), L).
% And no this line had no effect:
:- set_prolog_flag(double_quotes, chars).
Asked
Active
Viewed 67 times
-2

eguneys
- 6,028
- 7
- 31
- 63
1 Answers
0
How about:
% Show lists of codes nicely
:- portray_text(true).
moves([Move]) --> "move ", alnums(Move).
moves(Moves) --> "moves ", moves_list(Moves).
moves_list([Move|Moves]) --> alnums(Move), " ", moves_list(Moves).
moves_list([Move]) --> alnums(Move).
alnums([C|Cs]) --> alnum(C), alnums(Cs).
alnums([C]) --> alnum(C).
alnum(Digit) --> [Digit], { between(0'0, 0'9, Digit) }.
alnum(Lower) --> [Lower], { between(0'a, 0'z, Lower) }.
alnum(Upper) --> [Upper], { between(0'A, 0'Z, Upper) }.
Results in swi-prolog:
?- M = `move one`, once(phrase(moves(L), M)).
L = [`one`].
?- M = `moves one`, once(phrase(moves(L), M)).
L = [`one`].
?- M = `moves one two three`, once(phrase(moves(L), M)).
L = [`one`,`two`,`three`].

brebs
- 3,462
- 2
- 3
- 12
-
This works all great, though it is some verbose, with findall atom_codes. Why doesn't it just work natively with strings. – eguneys Jun 26 '22 at 19:42
-
Because what should the individual elements be - Unicode chars, ASCII chars, 0-255 numbers, or Unicode numbers? This way, it is unambiguous. Related: https://stackoverflow.com/questions/66301190/should-text-processing-dcgs-be-written-to-handle-codes-or-chars-or-both – brebs Jun 26 '22 at 20:16
-
Edited, to use `portray_text(true)` :-) – brebs Jun 27 '22 at 21:08