Consider the following Prolog code. It edits lines of a particular type in its input and prints out the remaining lines w/o any change. It uses a DCG called rule
which isn't included below, since it's not important to the question.
go:-
prompt(_, ''),
processInput.
processInput:-
read_line_to_codes(current_input, Codes),
processInput(Codes).
processInput(Codes):-
(Codes \= end_of_file
->
(phrase(rule(Part1, Part2), Codes)
->
format('~s - ~s\n', [ Part1, Part2 ])
;
format('~s\n', [ Codes ])),
processInput
;
true).
:- go, halt.
This works fine. However, suppose I change processInput/1
to the following, it just says that Warning: /home/asfernan/tmp/tmp.pl:28: Goal (directive) failed: user: (go,halt)
.
processInput(Codes):-
(Codes \= end_of_file
->
(\+phrase(rule(Part1, Part2), Codes)
->
format('~s\n', [ Codes ]))
;
format('~s - ~s\n', [ Part1, Part2 ]),
processInput
;
true).
The if & else parts of the phrase(r开发者_开发问答ule(Part1, Part2), Codes)
DCG match have been exchanged. This is obviously a newbie mistake, but the fact that go, halt
failed isn't very helpful. What can I do to make the error message indicate that the failure was because Part1
& Part2
were not bound in the format('~s - ~s\n', [ Part1, Part2 ])
line? I was able to track down this error because the code is small, but I may not have been able to do so had the code been big.
In Prolog the following is not the same:
..., ( Cond -> Then ; Else ), ...
and
..., ( \+ Cond -> Else ; Then ), ...
In general, a goal \+ Cond
will never instantiate its variables. So you
have to stick to the original formulation.
In case you are interested to process entire
files with DCGs, consider SWI's library(pio)
.
精彩评论