Reputation: 47
I don't understand why it doesn't work. I need to read the user's string and check if there are numbers, if so print them. I seem to have done this, but it won't work and I don't understand what's wrong...
word_digits( string, string ).
present_digits(string).
present_digits("") :- fail.
present_digits( S ) :-
frontchar( S, C, _ ),
C>='0',C<='9',!.
present_digits( S ) :-
frontchar( S, _, S2 ),
present_digits(S2).
word_digits( "", "" ) :- !.
word_digits( S, O ) :-
fronttoken( S, T, S2 ),
present_digits(T),
word_digits( S2, O2 ),
concat( T, " ", O3 ),
concat( O3, O2, O ), !.
word_digits( S, O ) :-
fronttoken( S, _, S2 ),
word_digits( S2, O ).
printThatShit:-
write( "Enter string: " ),
read(S), nl,
word_digits( S, Digits ),
write(Digits).
Upvotes: 0
Views: 151
Reputation: 2422
Your types are all over the place. In SWI-Prolog (which you are using) there are atoms, for example foo
and 'Another atom'
, and moreover:
?- atom_codes(foo, Codes).
Codes = [102, 111, 111].
?- atom_chars(foo, Chars).
Chars = [f, o, o].
?- atom_string(foo, String).
String = "foo".
If you solved that part in your code you will be much further than now.
Another hint: read
reads a Prolog term. If you want to just read some text, you need to read codes, chars, or an SWI-Prolog string. See read_line_to_codes
or read_line_to_string
or read_string
etc. Once you decide on the data type you can decide on how to get the digits (or numbers?) out: DCG, regexp, just simple filter on a list?
Assuming you already have a working solution (you should actually post it as an answer!)
This is one way to do it using a DCG:
:- use_module(library(dcg/basics)).
line_digits([D|Ds]) --> digit(D), !,
line_digits(Ds).
line_digits([]) --> "\n", !.
line_digits(Ds) --> [_],
line_digits(Ds).
only_digits -->
{ format("Enter string: "), flush },
line_digits(Ds),
{ format("~s~n", [Ds]) },
!,
only_digits.
only_digits --> eos.
To run it:
?- phrase_from_stream(only_digits, user_input).
Enter string: this is a string
Enter string: 234 this is another 3243 string999
2343243999
Enter string: ^D
true.
You stop it by typing Ctrl+D.
Quite a bit of code is needed to do the read-print loop. Maybe there is a cleaner way.
If you only had a list of say chars (one-character atoms) then this would be an easy way to do it:
only_digits(String, Digits) :-
include(digit, String, Digits).
digit(C) :- char_type(C, digit).
To use it:
?- only_digits([a,b,c,'1','2','3',x,y], Ds).
Ds = ['1', '2', '3'].
Upvotes: 1