I found out that with SWI-Prolog, the set_prolog_flag directive set_prolog_flag has a value in the source code file.
The only documentation I found about downloading source code files with directives was in Downloading Prolog Source Files
A directive is an instruction to the compiler. Directives are used for set (predicate) (see section 4.15), set flags (see set_prolog_flag / 2) and upload files (this section). Directives are form terms: - <term>.
Is there documentation for SWI-Prolog that covers downloading source code that notes whether the directive applies to the entire file or depends on the location in the source code file?
Or are all the lines loaded from the source code file just a game of operators at the top level, and location always matters?
Supplement / TL; DR
Default
When using Grammars (DCG) in Prolog, as you know, DCG requires the input list to be a list of character codes, for example.
?- string_codes("abc123",Cs). Cs = [97, 98, 99, 49, 50, 51].
and with the following DCG rule in the source file and uploaded to the top level
digit(0) --> "0".
DCG can be used with
?- string_codes("0",Cs),phrase(digit(D),Cs,R). Cs = [48], D = 0, R = []
set_prolog_flag
Now, to simplify the use of DCG instead of using the string_codes directive
:- set_prolog_flag(double_quotes, chars).
can be used in the source code file and with the following DCG rule in the source code file and loaded into the upper level
digit(0) --> "0".
DCG can be used with
?- phrase(digit(D),"0",R). D = 0, R = [].
There was nothing important about it.
It turns out that if set_prolog_flag appears before the DCG rule and then skips string_codes , but if set_prolog_flag appears after , the DCG rule then skips string_codes not working.
:- set_prolog_flag(double_quotes, chars). digit(0) --> "0". ?- phrase(digit(D),"0",R). D = 0, R = [].
vs
digit(0) --> "0". :- set_prolog_flag(double_quotes, chars). ?- phrase(digit(D),"0",R). false.
The motives that brought me to me
Although I know that a lot of programming with Prolog can only be done at the top level, I tend to rely on source and consult / 1 files.
When writing a lot of code, I started using modules . With modules, I found that Prolog flags are independent for each module.
?- current_prolog_flag(double_quotes,V). V = string. ?- current_prolog_flag(symbolic:double_quotes,V). V = string. ?- set_prolog_flag(symbolic:double_quotes,chars). true. ?- current_prolog_flag(double_quotes,V). V = string. ?- current_prolog_flag(symbolic:double_quotes,V). V = chars.
and that the default top-level module is user
?- current_prolog_flag(double_quotes,V). V = string. ?- current_prolog_flag(user:double_quotes,V). V = string. ?- set_prolog_flag(double_quotes,chars). true. ?- current_prolog_flag(double_quotes,V). V = chars. ?- current_prolog_flag(user:double_quotes,V). V = chars. ?- set_prolog_flag(user:double_quotes,codes). true. ?- current_prolog_flag(double_quotes,V). V = codes. ?- current_prolog_flag(user:double_quotes,V). V = codes.
which put me to the false belief that the Prolog directive set_prlog_flag applicable to the whole module no matter where it was written.
What broke the mold
When writing a large number of code examples, it was easier to save all the small examples in one file and the set_prolog_flag associated with each small example was. As an example of an identifier, he needed two small examples of DCG rules, one for numbers and one for letters. The rules of numbers were higher than the rules of writing and worked, but the rules of letters had the set_prolog_flag directive, because I was working on them at that time. Remember that I think the directive applies to the entire file at the moment. Then, when testing ident , the DCG rules for letters worked, but the DCG rules for numbers did not work.
digit(0) --> "0", !. digit(1) --> "1", !. digit(2) --> "2", !. :- set_prolog_flag(double_quotes, chars). ident(Id) --> letter(C), identr(Cs), { name(Id, [C|Cs]) }. identr([C|Cs]) --> letter(C), !, identr(Cs). identr([C|Cs]) --> digit(C), !, identr(Cs). identr([]) --> []. letter(a) --> "a", !. letter(b) --> "b", !. letter(c) --> "c", !. ?- phrase(ident(Id),"ab12",R). Id = ab, R = ['1', '2'].
Root cause
So using listing / 1
?- listing(digit). digit(0, [48|B], A) :- !, A=B. digit(1, [49|B], A) :- !, A=B. digit(2, [50|B], A) :- !, A=B.
?- listing(ident). ident(C, A, F) :- letter(D, A, B), identr(E, B, G), name(C, [D|E]), F=G. ?- listing(identr). identr([A|D], B, F) :- letter(A, B, C), !, E=C, identr(D, E, F). identr([A|D], B, F) :- digit(A, B, C), !, E=C, identr(D, E, F). identr([], A, A). ?- listing(letter). letter(a, [a|B], A) :- !, A=B. letter(b, [b|B], A) :- !, A=B. letter(c, [c|B], A) :- !, A=B.
the problem was obvious
digit(0, [48|B], A) :- !, A=B. letter(a, [a|B], A) :- !, A=B.
this digit was converted to use character codes 48 , and the letter was converted to use characters a . This is when I asked myself if the value of set_prolog_flag in the source.
Confirmation of the root cause
To test this, I created a small source code
digit_before(0) --> "0". :- set_prolog_flag(double_quotes, chars). digit_after(0) --> "0".
and at the top level
?- current_prolog_flag(double_quotes,V). V = string. ?- current_prolog_flag(symbolic:double_quotes,V). V = string. ?- consult("C:/Users/Eric/Documents/Projects/Calculus Project/test.pl"). true. ?- current_prolog_flag(double_quotes,V). V = chars. ?- current_prolog_flag(symbolic:double_quotes,V). V = string. ?- listing(digit_before). digit_before(0, [48|A], A). true. ?- listing(digit_after). digit_after(0, ['0'|A], A). true
which confirmed that the set_prolog_flag directive set_prolog_flag does not apply to the entire file. Note that digit_before is converted to 48 , and digit_after is converted to '0' .
Notes
Note. The set_prolog_flag(F,V) directive can also be used at the top level and does not require the foregoing :- .
Note. An example is used :- set_prolog_flag(double_quotes, chars). but :- set_prolog_flag(double_quotes, codes). . Using a chars value is preferred because it makes reading values ββeasier when debugging, etc.