Dynamic vs. Static Families. A common source of problems is that dynamic families are loaded/interpreted statically, or static families are loaded/interpreted dynamically. Try to keep this distinction straight: each file should contain only static or dynamic declarations. Common symptoms:
nat : type. s : nat -> nat. z : nat.are loaded dynamically, then we may get non-terminating behavior in circumstances where a free variable of type nat should remain in the answer. For example,
eq : nat -> nat -> type. id : eq N N. ?- eq N N.does not terminate if both eq and nat are dynamic. One should also keep in mind that it does not make sense for a static family to depend on a dynamic one. For example, if the query has the form a M1 ... Mn and a is a static type family then no free variable in M1 ... Mn will be solved, regardless of whether it is static or dynamic.
Whitespace and Identifiers. Unlike ML, even symbolic identifiers must be surrounded by whitespace. For example, a->b is one identifier. The only exceptions are the characters .:()[]{} which terminate identifiers.
Wildcards. Wild cards _ are existentially quantified when a clause is read, free variables (undeclared identifiers whose first letter is upper-case) are universally quantified! Wild cards should be used sparingly, and only if the omitted argument is uniquely determined by the context.
Static Scoping. After reloading an intermediate file, other files which depend on it must also be reloaded. Currently, if the checking of a file fails, none of the declarations in the file are entered into the top-level signature. I realize this is annoying on occasion, since we cannot re-check individual declarations unless the file has loaded successfully at least once. This particular feature might change in future versions.