Error and warning messages from programming systems like
SWI Prolog tell you that there is (or may be) a problem,
but they can be a little cryptic in terms of telling you
what the problem is. The following table is intended
to demystify the messages.
ERROR: Out of local stack
Look at your recursive rules and ensure that there is some
provision to stop the recursion from going on for ever.
Warning: (test.pl:1): Singleton variables: [Cihld]
test.pl
,at line 1 (that’s the
:1
), you have used avariable name that not used anywhere else in that rule
(or fact). Can mean a spelling mistake, as in this case —
Cihld
should presumably be Child
.However, it could just be that you really only wanted to
use the variable once, as with
Someone
, inhappy(Person) :- loves(Someone, Person).
In this case, you can get rid of the warning message by
putting an underscore in front of the singleton variable:
happy(Person) :- loves(_Someone, Person).
Warning: (thing.pl:3:31): Redefined static procedure rich/1
rich
was previously defined,and you have now loaded a new definition of it via
a
consult
operation. This will havecleared out the previous definition of
rich
.
Warning: (/Users/billw/or.pl:6): Clauses of rich/1 are not together in the source-file
procedure to be together, and for procedure
rich
this was not the case. Could have been intentional (which is
not to say a good idea) or maybe you goofed up and e.g.
repeated bits of code for
rich
in differentplaces in your source file.
ERROR: /Users/billw/thing.pl:1: No permission to redefine built-in predicate `assert/1' Use :- redefine_system_predicate(+Head) if redefinition is intended
It is usually a very bad idea to redefine a system predicate, as it
means that any other code that calls the system predicate may end
up using your definition, which might be entirely inappropriate.
It is usually better to think of another name for your predicate:
perhaps
make_assertion
instead of assert
in the example above.
If you absolutely have to use the name reserved for the system
predicate for some very good reason, you can do this by inserting
the directive
:- redefine_system_predicate(+Head).
e.g.
:- redefine_system_predicate(assert/1).
before the point where you begin to redefine the system predicate.
ERROR: /import/diskname/1/yourlogin/filename.pl:6: source_sink `nlp-basis.pro' does not exist Warning: /import/diskname/1/yourlogin/filename.pl:6: Goal (directive) failed: user:[nlp-basis.pro]
a directive like
:- ['nlp-basis.pro'].
to load some extra code into
Prolog, but there was no such file available. This could happen
either because, although the file exists, it’s in another directory,
or because you mis-spelled the filename. In this case, the file
is one that is often used in COMP9414 nlp assignments, and it is
spelled
nlpbasis.pro
not nlp-basis.pro
— i.e. no hyphen. Solution — fix the spelling of the filename in
your code. The :6: at the end of the first and third lines of the
messages is telling you that the problem was detected at line 6
of your code file. The extra «Warning» message is about the same
problem.
ERROR: /import/kamen/1/billw/filename.pl:12:0: Syntax error: Unexpected end of file
code stopped abruptly at line 12, without completing the rule or
fact that it was half-way through. This might be exactly what has
happened, or it might be that some syntax error in your code has
caused Prolog to get confused about what you are trying to do.
ERROR: /import/kamen/1/billw/filename.pl:92:0: Syntax error: Unexpected end of clause
code stopped abruptly at line 92, partway through a clause. This is
similar to the previous message, but Prolog had passed the start of
a clause when the problem occurred.
ERROR: /import/kamen/1/billw/filename.pl:41: Full stop in clause-body? Cannot redefine ,/2
warnings. Probably means you have a punctuation error in a rule,
something like this:
likes(Person1, Person2) :- friendly(Person1). shared_interests(Person1, Person2), pleasant(Person2).
There should be a comma, not a full stop, at the end of the first line.
ERROR: predname/1: Arguments are not sufficiently instantiated
predname
, probably apredefined one, and
you supplied an argument that was a variable that is yet bound,
where it doesn’t make sense to supply an unbound variable. For
example,
tab(N)
(which prints N
spaces)doesn’t make sense if
N
is not bound to a non-negativewhole number. The argument must be bound at the time the goal is
evaluated — it is not good enough to supply a value via a later
goal. The
/1
refers to the number of arguments thatpredname
takes, in this case 1, but will vary accordingto the number of arguments you provide to the particular predicate.
Like the preceding example errors, this one is likely to come, in
practice, with a filename:linenum:position to tell you where in
your program the problem is located.
ERROR: predname/1: Type error: `character' expected, found `abc'
argument — maybe integer, or string, for example. In this case,
the predicate
predname
was expecting a single character, butyou provided the string
'abc'
.Like preceding example errors, this one is likely to come, in
practice, with a filename:linenum:position to tell you where in
your program the problem is located.
I plan to add to the table as I encounter more such messages.
Suggestions welcome, please send a cut-and-paste of the message,
the dialogue with SWI Prolog that generated it,
and the Prolog code as an attachment. This is not a free debugging service,
but I’ll try to include such examples in this list.
У пролога есть ряд функций, обеспечивающих ввод и вывод:
- read/1 осуществляет ввод терма с входного потока, на прологе они завершаются точкой. Термами являются, например, числа, строки (в одинарных кавычках) и списки (в том числе списки символов и кодов символов).
- readln/1 считывает символы до конца строки, формируя список слов (в одинарных кавычках);
- get_char/1 считывает с потока один символ, используя синхронный ввод (если ввод осуществляется с клавиатуры, то функция не начнет работу, пока пользователь не нажмет Enter);
Но мой взгляд, достаточно удобно обрабатывать строки на SWI Prolog в виде списка кодов символов (они хранятся при этом в юникоде). Для ввода строк я использую вот функцию rd_line:
%% считывает список кодов с текущего устройства ввода rd_line(Str):- get_code(H), ( code_type(H, end_of_line), !, Str = []; code_type(H, end_of_file), !, Str = []; Str = [H|T], rd_line(T) ).
Тут вызывается функция get_code, возвращающая код символа (аналогично get_char). Если текущий символ представляет собой конец строки или файла — результатом является пустая строка (пустой список кодов). В противном случае выполняется рекурсивный вызов для считывания остальных символов.
Если требуется осуществить ввод из файла — можно установить файл в качестве основного устройства ввода. После этого функции read и т.п. будут работать с ним точно также, как с буфером клавиатуры или экраном:
- see/1, принимает ‘имя файла’, открывает файл для чтения, устанавливает его в качестве текущего потока ввода. После вызова предиката весь ввод осуществляется с открытого файла;
- seen/0, закрывает файл, ассоциированный с текущим потоком ввода. После вызова этого предиката ввод осуществляется с клавиатуры;
- tell/1, тоже самое, что see, но открывает файл для записи и устанавливает в качестве потока вывода;
- told/0, закрывает файл открытый tell. После вызова, весь вывод попадает на экран.
Такой вариант не сработает если вам надо работать одновременно с несколькими файлами. В этом случае надо использовать версии функции read, get_char и т.п., принимающие имя открытого файлового потока в качестве дополнительного аргумента. Открыть потом можно функцией open, а закрыть — close, работа с потоками в SWI Prolog мало отличается от других языков.
В вашем случае строки не считывались, т.к. вы используете функцию read, которая считывает термы. Поставьте точки в конце строк и она их считает.
using stream function to read term in a txt file all example in forum failed ,to read term in txt,why this powerful development tool can’t do this easy work,
I don’t know what kind of problem are you experiencing. As of my experience Visual Prolog 7.4 is really awesome and simple compared to other lower version..
Can you please share the code that you’ve tried and which caused the failure for you ?
Example #1 :
If you are trying to read a data from file and want to consult with the internal Data base, here is the way,
Code: Select all
%Define a database
class facts - myTerm
myTerm1 : (string, string, integer).
myTerm2 : (integer, string, integer).
myTerm3 : (integer).
myTerm4 : (integer, char).
predicates
onPushButtonClick : button::clickResponder.
clauses
onPushButtonClick(_Source) = button::defaultAction:-
%Consult it - this will bring all the data from file to IDB
file::consult(@"E:Term_Input.txt", myTerm),
!.
File data : E:Term_Input.txt
myTerm1(«Welcome», «To», 1)
myTerm1(«Nice», «see», 1)
myTerm2(10, «Ten», 1)
myTerm2(20, «Twenty», 1)
myTerm3(100)
myTerm3(200)
myTerm4(100, ‘A’)
myTerm4(200, ‘B’)
Example #2:
To read a data from one file and write into another file,
Code: Select all
predicates
copyTextStream : (inputStream In, outputStream Out).
clauses
copyTextStream(In, Out) :-
if not(In:endOfStream()) then
Out:write(In:readline(), "n"),
copyTextStream(In, Out)
end if.
predicates
onPushButtonClick : button::clickResponder.
clauses
onPushButtonClick(_Source) = button::defaultAction:-
InputFile = inputStream_file::openFile8("E:\test.txt"), %Input file
OutputFile = outputStream_file::openFile8("E:\test2.txt"), %Output file
copyTextStream2(InputFile, OutputFile), %Calling place for looping
%You must close the stream after you complete your progress
InputFile:close(),
OutputFile:close(),
!.
At the end, whatever the data reside on the Input file will be written on the output file —