我的一项任务要求我们建立一个prolog tokenizer。现在我写了一个可以改变空间并将其换成新行的谓词。但我不知道如何将其实施到主程序中。
替换部件如下所示:
replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]):- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).
Main
部分有一个名为removewhite(list1 list2)
那么如何让removewhite
执行替换?
答案 0 :(得分:5)
你对一个标记器有点'偏离':removewhite / 2不会给你带来任何有用的功能。相反,请考虑使用DCG(当然,如果您的Prolog提供此功能):
tokenize(String, Tokens) :- phrase(tokenize(Tokens), String).
tokenize([]) --> [].
tokenize(Tokens) --> skip_spaces, tokenize(Tokens).
tokenize([Number|Tokens]) --> number(Number), tokenize(Tokens).
skip_spaces --> code_types(white, [_|_]).
number(N) --> code_types(digit, [C|Cs]), {number_codes(N,[C|Cs])}.
code_types(Type, [C|Cs]) --> [C], {code_type(C,Type)}, !, code_types(Type, Cs).
code_types(_, []) --> [].
尽管简单,但它是一种相当高效的扫描仪,易于扩展。 在SWI-Prolog中,它具有(非ISO兼容)扩展以有效处理字符串,这可以从顶层调用,如:
?- tokenize(`123 4 567 `, L).
L = [123, 4, 567]
或
?- atom_codes('123 4 567 ',Cs), tokenize(Cs, L).
Cs = [49, 50, 51, 32, 32, 52, 32, 53, 54|...],
L = [123, 4, 567]
顺便说一句,在SWI-Prolog中,数字// 1是library(dcg/basics)预定义的(当然还有更多功能)。
无论如何,关于你的问题
如何让removewhite执行replace?
我觉得你真的'吠叫错误的树':删除一个空间 - 实际上 分隔符 - 会搞砸你的输入...
答案 1 :(得分:1)
你可以写一个更强大的"强大的"谓词
replace_all(_, _, [], []).
replace_all(L, R, [X|T], [R|T2]):-
member(X, L),
replace_all(L, R, T, T2).
replace_all(L, R, [X|T], [X|T2]) :-
\+ member(X, L),
replace_all(L, R, T, T2).
然后,你将有
removewhite(List1, List2) :-
remove_all([' ', '\t'], '\n', List1, List2).