Appendix B. Compiler Errors and Warnings

This section gives a partial listing and explanation of compiler error and warning messages.

B.1. MULTIPLE_VALUES

Predicates with multiple value arguments are only allowed in query blocks, not active blocks.

a(x) -> .
q(x;y,z) -> a(x), a(y), a(z).
block multiple-values: line 2: error: Predicate  'q' with database lifetime cannot have
more than one value argument. (code: MULTIPLE_VALUES)
    q(x;y,z) -> a(x), a(y), a(z).
    ^^^^^^^^

B.2. EDB_RULE

By default writing IDB rules for EDB predicates will cause the runtime to clear the contents of the EDB and change the predicate's derivation type to "DerivedAndStored". To avoid this happening accidentally, it is possible to specify the derivation type of an EDB predicate as "Extensional". This will indicate to the compiler that it is intended for the predicate to always be an EDB.

If an IDB rule is written for an EDB predicate with a derivation type of "Extensional", the compiler will detect this and report an EDB_RULE error.

e(x) -> int[64](x).
lang:derivationType[`e]="Extensional".

e(x) <- x = 3. // EDB_RULE error

B.3. DIV_ZERO

This error is reported when the compiler is certain that a divide by zero will occur in the given logic. The analysis used by the compiler is conservative and will likely not detect some divisions by zero.

p(x) -> int[64](x).
p(x) <- x = 10/0.  // DIV_ZERO error
p(x) <- x = 8/y, y = 0. // no DIV_ZERO error

B.4. NO_DECLARATION

The compiler will infer the predicate declarations for some predicates that appear in logic. However, sometimes this can lead to the compiler not reporting an error, or at least the real error, when a predicate name is misspelled. The pedantic warning NO_DECLARATION reports when a predicate declaration has been inferred for a predicate, which could be a sign that the predicate's name has been misspelled.

foo(x) -> int(x).
foa(x) <- x = 3.  // NO_DECLARATION

B.5. CONSTRUCTOR_ILLEGAL_VALUETYPE

This error is triggered when a predicate is declared constructor for a non-entity type. For instance:

myConstuctor[]=p -> string(p).
lang:constructor(`Constuctor).

B.6. SIMILAR_VAR

One source of errors is the misspelling of variable names. Although this mistake is sometimes caught through the VARIABLE_SOLITARY warning, when the misspelling is common, these errors can be hard to catch. The pedantic warning SIMILAR_VAR is reported when two variables are similar to each other based upon the number of edits needed to convert one variable to the other.

The maximum edit distance used for determining similarity can be set through the environment variable BLOXCOMPILER_EDIT_DISTANCE. The default edit maximum edit distance is 2. Variables shorter than the maximum edit distance will not be considered.

a(x) -> int[32](x).
a(foa) <- foo=5, fob=3, foa = foo + fob.
// SIMILAR_VAR: foa and foo, foa and fob, foo and fob.

B.7. SUBTYPE_MULTI

The compiler reports this warning when an entity is declared with more than one superentity. The current treatment of entities with more than single superentity is sometimes inconsistent and can lead to subtle errors. Entities with more than one superentity will be disallowed in the future.

B.8. DYNAMIC_TYPE_CONSTRAINT

Some integrity constraints, such as type declarations, can be checked entirely statically, while some must be deferred and checked at runtime. These runtime checks carry a performance penalty. It can be easy to inadvertently incur that penalty by writing integrity constraints that appear to be type declarations but are not, or contain subformulas that must be checked dynamically.

The pedantic warning DYNAMIC_TYPE_CONSTRAINT is used to inform the user of which formulas in a constraint that appears to be a type declaration may have to be checked at runtime.

p(x,y) -> int(x), int(y).
r(x) -> int(x).

p(x,y) -> r(x), r(y). // DYNAMIC_TYPE_CONSTRAINT: r(x), r(y)

B.9. POLYMORPHIC_LITERAL

Polymorphic predicates such as eq_2 and add are not true predicates and exist only as a convenience for the user. They are always converted by the compiler to a specific type predicate, such as int:eq_2 or float:add. To do that, the compiler uses the inferred types of the predicate's arguments. However, when one of these polymorphic predicates is written as as a literal (e.g., as an argument to a pragma), it may be impossible to infer from the context the typed predicate to which is should be converted. Therefore, using polymorphic predicates in predicate literals is disallowed. If you know what type the predicate should be instantiated with, write the specific typed predicate literal instead.

lang:pulse[`add] = 0.0.  // error POLYMORPHIC_LITERAL

B.10. COMP_UNORDERED

Entities may only be compared with = and !=. This error occurs when comparing entities with > or other ordered comparisons.

B.11. MULTI_ENTITY_CREATION

A rule is attempting to create an entity using two instances of a constructor or refmode. For instance, the following program has this error.

e(x), e_ref(x:y) -> string(y).

please_ins() -> .

+e_ref(x,"hello"), +e_ref(x,"goodbye"), +e(x) <- +please_ins().

Was MULTI_SKOLEM_ONE_VAR prior to LogicBlox 3.9, and MULIT_CONSTRUCTOR_ONE_VAR prior to LogicBlox 4.0.4.

B.12. SEVERITY_INCONSISTENT

The program contains conflicting severity pragmas.

lang:compiler:error:HEAD_VAR_UNBOUND[] = true.
lang:compiler:error:HEAD_VAR_UNBOUND[] = false.
2| lang:compiler:error:HEAD_VAR_UNBOUND[] = false.
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

inconsistent severity declaration for problem HEAD_VAR_UNBOUND (Warning SEVERITY_INCONSISTENT)

Some severity pragmas are set automatically by the runtime. In this case even a single severity pragma may trigger the error. For instance the following script will also trigger SEVERITY_INCONSISTENT.

create --unique
addblock 'lang:compiler:disableError:DELTA_UNGUARDED[] = true.'

B.13. Hierarchical syntax

B.13.1. HIER_NO_ENCLOSING

This error is reported if you write a hierarchical expression that is not written inside a hierarchical formula.

person(p) -> .
name[p]=s -> person(p), string(s).

address(a) -> .
street[a]=s -> address(a), string(s).

home[a]=p -> person(p), address(a).

favorite(p) -> person(p).

person(p),
name[p]="Bill",
home[address(_) { street("Anywhereville") }]=p
<- favorite(p).
block HIER_NO_ENCLOSING: line 13: error: this hierarchical expression does not have an
enclosing hierarchical formula. (code: HIER_NO_ENCLOSING)
    home[address(_) { street("Anywhereville") }]=p
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

B.13.2. HIER_HEAD_NOT_ATOM

This error is reported if you write a formula in the head of a hierarchical formula that is not an atom.

t() ->.
a(x) ->.
foo(x, y) -> a(x), int(y).

t() <- (x < 1, a(_)) { foo(x) }.
block HIER_HEAD_NOT_ATOM: line 5: error: in the current implementation of hierarchical
syntax, the head of a hierarchical formula, must consist entirely of conjunctions of
atoms. (code: HIER_HEAD_NOT_ATOM)
    t() <- (x < 1, a(_)) { foo(x) }.
            ^^^^^

block HIER_HEAD_NOT_ATOM: line 5: error: in the current implementation of hierarchical
syntax, the head of a hierarchical formula, must consist entirely of conjunctions of
atoms. (code: HIER_HEAD_NOT_ATOM)
    t() <- (x < 1, a(_)) { foo(x) }.
            ^^^^^

B.13.3. HIER_NO_CANDIDATES

This error is reported if there are no candidate expressions in the head of a hierarchical formula.

t() ->.
foo(x) -> int(x).

t() <- t() { foo() }.
block HIER_NO_CANDIDATES: line 4: error: there are no candidate expressions in the head
of the enclosing hierarchical formula, but there are fewer user supplied arguments than
the predicate foo expects. (code: HIER_NO_CANDIDATES)
    t() <- t() { foo() }.
                 ^^^^^

B.13.4. HIER_CANDIDATE_NO_TYPE

This error is reported when no type can be inferred for a candidate expression in the hierarchical head.

B.13.5. HIER_ARG_TYPE_NOT_KNOWN

This error is reported when a predicate without a declaration is used in the body of a hierarchical formula. Because the predicate has no declaration, there is no way to be sure what the correct number and type of arguments should be for this predicate and whether it requires any insertions from the hierarchical head.

B.13.6. HIER_UNSUPPORTED_EXPR

Currently, candidate expressions may only be literals or variables. This error is reported when the compiler finds some other sort of expression in the head of a hierarchical formula.

t() ->.
foo(x) -> int(x).

t() <- foo(2 + 3) { t() }.
5| t() <- foo(2 + 3) { t() }.
              ^^^^^

currently only variables and literals may be used as candidate expressions. (Error HIER_UNSUPPORTED_EXPR)

B.13.7. HIER_AMBIGUOUS_HEAD_BINDING

This error is reported if the head of a hierarchical formula contains two or more candidate expressions that have non-disjoint types. Roughly, disjoint means that the type of the expressions types are not subtypes of each other.

a(x) ->.
foo(x, y) -> a(x), a(y).
t() ->.

t() <- foo(x, y) { foo(x, y) }.
block HIER_AMBIGUOUS_HEAD_BINDING: line 5: error: the head of this hierarchical formula
contains two binding with non-disjoint types: y and x.  Therefore, it is not possible to
unambiguously determine which expression should be used for insertion in the body of the
hierarchical formula. (code: HIER_AMBIGUOUS_HEAD_BINDING)
    t() <- foo(x, y) { foo(x, y) }.
           ^^^^^^^^^^^^^^^^^^^^^^^

B.13.8. HIER_EXPR_NOT_ENTITY

This error is reported when the head of a hierarchical expression is not a single atom that is an entity.

person(p) -> .

address(a) -> .
street[a]=s -> address(a), string(s).

home[p]=a -> person(p), address(a).

favorite(p) -> person(p).

foo(a, p) -> address(a), person(p).

person(p) {
  home( foo(_, _) { street("Anywhereville") })
} <- favorite(p).
block HIER_EXPR_NOT_ENTITY: line 12: error: the head of this this hierarchical
expression, foo(_, _), is not an entity. (code: HIER_EXPR_NOT_ENTITY)
    person(p) {
      home( foo(_, _) { street("Anywhereville") })
    } <- favorite(p).
    ^

B.13.9. HIER_ATOM_TOO_MANY_SUPPLIED

This error is reported when the user has supplied more arguments to a hierarchical atom than are needed.

a(x) ->.
b(x) ->.
foo(x, y) -> a(x), b(y).
t() ->.

t() <- (a(_), b(y)) { foo(y) }.
block HIER_ATOM_TOO_MANY_SUPPLIED: line 6: error: this hierarchial atom contains 1 user
supplied key(s), yet only 0 user supplied key(s) are needed in this context (code:
HIER_ATOM_TOO_MANY_SUPPLIED)
    t() <- (a(_), b(y)) { foo(y) }.
                          ^^^^^^

B.13.10. HIER_ATOM_TOO_FEW_SUPPLIED

This error is reported when the user has supplied fewer arguments to a hierarchical atom than are needed.

a(x) ->.
b(x) ->.
foo(x, y) -> a(x), b(y).
t() ->.

t() <- a(_) { foo() }.
block HIER_ATOM_TOO_FEW_SUPPLIED: line 6: error: this hierarchial atom contains 0 user
supplied key(s), yet 1 user supplied key(s) are needed in this context (code:
HIER_ATOM_TOO_FEW_SUPPLIED)
    t() <- a(_) { foo() }.
                  ^^^^^

B.14. Delta logic

B.14.1. DELTA_UNGUARDED

This compile-time error is raised when attempting to install a delta rule that does not have any delta or pulse predicates in the body of the rule. If allowed, such rules could harm performance.

Two examples:

retailLogic: line 5: warning: installed delta rules are evaluated in
every transaction if they are not guarded by at least one delta or
pulse predicate in the body of the rule. Because this requires a write
lock on the predicate, this can have significant impact on
performance, in particular in concurrent systems. (code:
DELTA_UNGUARDED)

^filterTestPred(sk, w; ) <- Product:Sku(sk), Calendar:Week(w), Calendar:Week:id(w; "week_2").
suite.program: line 23: warning: installed delta rules are evaluated
in every transaction if they are not guarded by at least one delta or
pulse predicate in the body of the rule. Because this requires a write
lock on the predicate, this can have significant impact on
performance, in particular in concurrent systems. (code:
DELTA_UNGUARDED)

+map(x;y) <- dimX:val(x:2), dimY:val(y:2).

B.14.2. NEGATED_UNGUARDED

This error occurs when you have written delta rule to be executed at a stage other than INITIAL that references a negated atom from an earlier stage. Furthermore, that atom contains existentially quantified variables. For example,

+p(x) <- +r(x), !q@prev(y, x).

If this delta rule is compiled to run at stage final, the rule would trigger the error. Here, the contents of the predicate q are being queried for the previous stage, and q references the existentially quantified variable y.

The reason this error is reported is because negated formulas with existentially quantified variables cannot be executed directly. Instead, the compiler generates a projection predicate that materializes the negated atom. For example, the compiler could rewrite the above delta rule as

+p(x) <- +r(x), !_projection(x).
+_projection(x) <- q@prev(y, x).

The problem with this rewrite is that in this specific case the conditions are such that the projection rule generated by the compiler would have produced a DELTA_UNGUARDED warning from the compiler if the logic had been written this way originally. To avoid having the compiler rewrite a program into one that may perform badly for no apparent reason, we instead report an error.

The error can be resolved by manually providing the projection. If the original example was rewritten as shown above, a DELTA_UNGUARDED warning would be reported, but the logic would compile. In practice, it would be better to write the projection so that it included a reference to a relevant delta or pulse predicate in its body. For example, given our original example, the following logic would be a reasonable replacement

+p(x) <- +r(x), !_projection(x).
+_projection(x) <- +r(x), q@prev(y, x).

Here we have guarded the projection rule with a reference to '+r(x)'.

This error may be removed in the future.

B.15. Aggregations

B.15.1. AGG_PARSE

This error is reported when the compiler cannot parse the aggregate operations.

B.15.2. AGG_KEY_OUTPUT

This error is reported when an output of an aggregation is used as a key in a head atom. We presently cannot evaluate such logic, so we reject this at compile-time.

B.15.3. AGG_VALUE_NON_OUTPUT

This error is reported when the value arguments of a functional predicate in the head of an aggregation are not outputs to the aggregation. We presently cannot evaluate such logic, so we reject this at compile-time.

B.16. Entities

B.16.1. PULSE_ENTITY_IN_DB_LIFETIME

a(x) -> .
p(x) -> a(x).

lang:pulse(`a).
block pulse-entity: line 2: error: event entity 'a' cannot be used as an argument of
database lifetime predicate 'p' (code: PULSE_ENTITY_IN_DB_LIFETIME)
    p(x) -> a(x).
    ^^^^

block pulse-entity: line 2: warning: A constraint with a pulse or delta on its RHS very
likely needs a pulse or delta in its LHS (code: PULSE_CONSTRAINT)
    p(x) -> a(x).
    ^^^^^^^^^^^^

B.17. Incremental Evaluation

B.17.1. INCR_NONDET

The database engine evaluates installed, non-delta logic rules incrementally: computed results are stored, and future transactions only recompute those changes that may be caused by changes in the predicates that occur in the body of the rule. That is, existing results that are not invalidated are assumed to be still correct. For non-deterministic features, it is actually incorrect to store the results, since they can change in every single transaction. Such non-deterministic logic features can therefore be used only in logic that is fully evaluated, i.e., any rule in queries or delta rules in installed blocks. If you do use these features, then you should be aware that the application might work with results that are logically incorrect.

s[] = datetime:now[].
's[] = datetime:now[].'
Exception in command: Operation failed:
ERROR BloxCompiler reported errors:

block block_1Z1LO6CH: line 1: error: non-deterministic built-in predicate 'datetime:now' changes in every transaction and should not be used in an installed non-delta rule. Installed non-delta rules are re-evaluated incrementally in every transaction. Incremental evaluation assumes that only changes in predicate 'datetime:now' need to be considered in re-evaluation, which is logically incorrect for non-deterministic built-in predicates. (code: INCR_NONDET)
     s[] = datetime:now[].
           ^^^^^^^^^^^^^^

B.18. File predicates

B.18.1. FILE_PREDICATE_STAGES

fp-stage2.logic: line 9: error: file predicate '_file' is
used with a stage modifier, but file predicates do not support stages
(code: FILE_PREDICATE_STAGES)

+_fun(x,y) <- _file@prev(x,y).
^^^^^^^^^^^^^^^

B.18.2. FILE_PREDICATE_DELTA

File predicates do not support delta modifiers.

fp.logic: line 9: error: file predicate '_file' cannot have a
delta modifier in the body of a rule (code: FILE_PREDICATE_DELTA)
+a(x,y) <- +_file(x,y).
^^^^^^^^^^^

B.18.3. FILE_PREDICATE_RECURSION

File predicates cannot be used in recursion.

lang:physical:filePath[`_in] = "simple_import.csv".

_p(x) -> string(x).
_in(x) -> string(x).

_in(x) <- +_p(x).
+_p(x) <- _in(x).

6| _in(x) <- +_p(x).
   ^^^^^^^^^^^^^^^^

file predicate 'test:_in' cannot be used in recursion:
   ----
   '+test:_in@INITIAL' depends on (via rule at line 6 of block test: 'test:_in(x)
  <- +test:_p(x)')
   '+test:_p@INITIAL' depends on (via rule at line 7 of block test: '+test:_p(x)
  <- test:_in(x)')
   'test:_in@INITIAL' depends implicitly on (via implicit frame rule: 'test:_in@INITIAL <- +test:_in@INITIAL')
   '+test:_in@INITIAL'
   ----
 (Error FILE_PREDICATE_RECURSION)

B.18.4. FILE_PREDICATE_INACTIVE

File predicates can only be used in inactive blocks.

B.19. Derived-only predicates

B.19.1. DERONLY_PULSE

Derived-only pulse predicates may only be defined via event rules.

B.19.2. DERONLY_RECURSION

Derived-only predicates cannot be recursively defined.

lang:derivationType[`p] = "Derived".
lang:derivationType[`q] = "Derived".

p(x) <- x = 3.
p(x) <- x = 5, q(x).
q(x) <- p(x).
block deronly-recursion: line 5: error: predicate 'p' is a derived-only predicate
recursively defined using its own values, through the following rules:
   ----
   'p@FINAL' depends on (via rule at line 5 of block deronly-recursion: 'p(5)
  <- , q(5)')
   'q@FINAL' depends on (via rule at line 6 of block deronly-recursion: 'q(x)
  <- p(x)')
   'p@FINAL'
   ----
 (code: DERONLY_RECURSION)
    p(x) <- x = 5, q(x).
    ^^^^^^^^^^^^^^^^^^^

block deronly-recursion: line 6: error: predicate 'q' is a derived-only predicate
recursively defined using its own values, through the following rules:
   ----
   'q@FINAL' depends on (via rule at line 6 of block deronly-recursion: 'q(x)
  <- p(x)')
   'p@FINAL' depends on (via rule at line 5 of block deronly-recursion: 'p(5)
  <- , q(5)')
   'q@FINAL'
   ----
 (code: DERONLY_RECURSION)
    q(x) <- p(x).
    ^^^^^^^^^^^^