Prolog Flags¶
set_prolog_flag/2 and current_prolog_flag/2 read and change the Prolog
flags of ISO 13211-1 (7.11, 8.17), plus one flag of Clausal Prolog's own,
assert_creates_dynamic.
Flag names and values are atoms. In seam (.seam) source, write them quoted
('unknown'), or declare them with -private([...]), as with any atom. A
truth value is true / false, which compile to Python's True / False.
The flags¶
| Flag | Value here | Settable | Scope | Scryer |
|---|---|---|---|---|
bounded |
false |
no | process | false |
max_integer |
none (integers are unbounded) | no | process | none |
min_integer |
none | no | process | none |
integer_rounding_function |
toward_zero |
no | process | none (the query fails) |
char_conversion |
off |
off only |
process | not a flag |
debug |
off |
on / off |
process | not a flag |
max_arity |
unbounded |
no | process | 255 |
unknown |
error |
error only |
process | error (settable) |
double_quotes |
chars |
by directive | module | chars |
assert_creates_dynamic |
false (true in a .clausal or imported .pl module) |
yes | module | not a flag (ISO assert always creates) |
require_end_module |
default |
true / false / default |
process (file-local as a .pl directive) |
not a flag |
- Integers are unbounded (Python
int), soboundedisfalseandmax_integer/min_integerhave no value:current_prolog_flag('max_integer', X)fails, as in Scryer. integer_rounding_functionistoward_zero: the ISO evaluable'//'(-7, 2)is-3. (A bare-7 // 2in source is Python's floor division, which is not the ISO evaluable; see Operators.)max_arityisunbounded: a compound term is a Python tuple, and there is no arity limit.unknownis alwayserror: calling an unknown procedure raisesexistence_error(procedure, PI). The ISO valuesfailandwarningare not implemented.debugcan be set, but changes nothing yet.double_quotesis the module's-double_quotesmode:chars(the default:"…"is a string) oratom. It decides how the compiler reads the module's"…"literals, so it is set by a directive, never at run time.codesis not a mode: codes are spelledb"…".assert_creates_dynamic: see below.require_end_module: whether a Prolog module file must end with:- end_module(Name).-- see Importing Prolog Code.
current_prolog_flag(F, V) with F unbound enumerates every flag that has a
value.
test("bounded") <- current_prolog_flag('bounded', false)
test("unknown is error") <- current_prolog_flag('unknown', 'error')
test("no max_integer") <- (not current_prolog_flag('max_integer', _M))
test("enumerate") <- (
findall(F, current_prolog_flag(F, _V), FLAGS),
in_('double_quotes', FLAGS)
)
Scope¶
A process flag has one value for the whole process.
A module flag has a value per module:
set_prolog_flag/2, run as a goal, sets it for the calling module;current_prolog_flag/2reports the calling module's value;- the directive
-set_prolog_flag(Flag, Value)sets it for the module that carries the directive.
test("a module flag") <- (
set_prolog_flag('assert_creates_dynamic', true),
current_prolog_flag('assert_creates_dynamic', true)
)
The directive¶
-set_prolog_flag(Flag, Value) sets a flag when the module loads. For
double_quotes it is the same as -double_quotes(Value), and like that
directive it governs the literals below it. A setting that set_prolog_flag/2
would refuse is a load-time SyntaxError that carries the ISO error term.
Errors¶
The errors are ISO's (8.17.1.3, 8.17.2.3). The context is
set_prolog_flag/2 or current_prolog_flag/2.
| Case | Error |
|---|---|
Flag or Value unbound |
instantiation_error |
Flag not an atom |
type_error(atom, Flag) |
Flag not a flag |
domain_error(prolog_flag, Flag) |
Value not a value ISO allows for the flag |
domain_error(flag_value, Flag+Value) |
a read-only flag, or an ISO value this engine does not implement (unknown = fail, char_conversion = on, double_quotes = codes), or double_quotes set at run time |
permission_error(modify, flag, Flag) |
Scryer departs from ISO on two rows. It reports a read-only flag
(set_prolog_flag(max_arity, 5)) and a bad unknown value as
domain_error(prolog_flag, Flag). Here ISO decides.
test("not a flag") <- catch(
set_prolog_flag('nosuch', 1),
error(domain_error('prolog_flag', 'nosuch'), _),
true)
test("read-only") <- catch(
set_prolog_flag('bounded', true),
error(permission_error('modify', 'flag', 'bounded'), _),
true)
test("not a value") <- catch(
set_prolog_flag('unknown', 'bogus'),
error(domain_error('flag_value', '+'('unknown', 'bogus')), _),
true)
assert_creates_dynamic¶
What assertz/1 and asserta/1 do with a procedure that does not exist yet.
false(the default in.seammodules): the dynamic database is declare-first. Asserting into a procedure nothing declares raisespermission_error(modify, static_procedure, PI), because ISO makes an undeclared procedure static (7.5.2). Declare it with-dynamicfirst.true(the default in a Clausal Prolog.clausalmodule and in an imported.plmodule): ISO 7.5.2(2). Asserting into a procedure that does not exist creates it, as a dynamic procedure of the module.
With either value, these are still refused with
permission_error(modify, static_procedure, PI):
- a static predicate that has clauses;
- a builtin;
- a declared data functor.
The flag is module-scoped: it governs asserts into the module whose flag is set.
-set_prolog_flag(assert_creates_dynamic, true)
remember(X) <- assertz(seen(X))
test("assertz creates the procedure") <- (
remember(1),
remember(2),
findall(X, seen(X), XS),
XS == [1, 2]
)
A Clausal Prolog (.clausal) module or an imported Prolog module starts with
assert_creates_dynamic set to true. A
:- set_prolog_flag(assert_creates_dynamic, false). in the file turns it off.
See also: Database Operations — assertz, asserta, retract; Directives; Importing Prolog Code.