Var
A logic variable, i.e. a placeholder for a Term that is yet to be determined.
A Var is created out of a simple, human-readable name (e.g. X), but its real identity is its completeName, which pairs name with a hidden, per-name sequential id. This is why, perhaps surprisingly, Var.of("X") == Var.of("X") is always false: each call mints a genuinely new variable, and relying on the name alone for equality would make every clause containing a variable called X accidentally alias every other clause using that same name. See the "Variables and Scoping" explanation page in the project documentation for the full rationale.
Because of this, code that needs to refer to the same variable more than once while building a term (e.g. member(H, [_|T]) :- member(H, T)., where H and T each occur twice) should not call Var.of repeatedly with the same name: doing so creates unrelated variables. Instead, either keep a single Var reference around and reuse it, or use a Scope, which caches variables by name and hands back the same instance on repeated requests:
Scope.of("H", "T") {
ruleOf(structOf("member", varOf("H"), consOf(anonymous(), varOf("T"))), structOf("member", varOf("H"), varOf("T")))
}The anonymous variable (conventionally named _) is the deliberate exception to variable reuse: every call to anonymous (or Var.anonymous) produces a fresh, unrelated variable, matching Prolog's convention that _ never binds to anything meaningful shared across occurrences.
See also
Properties
The full identity of this variable, obtained by combining name and id (e.g. "X_1"). Two Var instances are equals to each other (via Term.equals(Any?)) if and only if their completeNames match; see Term.equals for how to compare variables by name alone instead.
The identifier distinguishing this variable from any other Var sharing the same name. Combined with name, it forms completeName. Identifiers are assigned automatically and cannot be chosen by client code, precisely so that no two independently-created variables can accidentally collide.
Whether this variable is the anonymous variable, i.e. whether its name is "_". Anonymous variables are never meant to be shared: each one created via Var.anonymous is distinct, regardless of this property being true for all of them.
Checks whether the current term is a constant, i.e., either an atom or a number. This method is guaranteed to return true if and only if the current term is an instance of Constant.
Checks whether the current term is a directive. This method is guaranteed to return true if and only if the current term is an instance of Directive.
Checks whether the current term is an empty logic block. This method is guaranteed to return true if and only if the current term is an instance of EmptyBlock.
Checks whether the current term is an empty logic list. This method is guaranteed to return true if and only if the current term is an instance of EmptyList.
Checks whether the current term is the either the fail atom or the false atom. This method is guaranteed to return true if and only if the current term is an instance of Truth and its Truth.value is "fail" or "false".
Checks whether the current term is an indicator. This method is guaranteed to return true if and only if the current term is an instance of Indicator.
Whether name matches NAME_PATTERN, i.e. whether it could legally appear as a variable name in Prolog syntax. This is purely informational: constructing a Var via Var.of never validates or throws because of an ill-formed name.
Checks whether the current term is a recursive structure, i.e., a list, a tuple, or a block. This method is guaranteed to return true if and only if the current term is an instance of Recursive.
Checks whether the current term is the true atom. This method is guaranteed to return true if and only if the current term is an instance of Truth and its Truth.value is "true".
The simple, human-readable name of this variable, as it would appear in Prolog source (e.g. "X"). This is not used to determine variable identity/equality; see completeName for that.
The sequence of Variables directly or indirectly contained in the current object. Variables are lazily returned in a non-deterministic order. Notice that no occurrence-check is performed. Thus, if a Term contains the same Variable twice or more times, then the variables sequence may contain as many occurrences of that Variable
Functions
Lets the provided TermVisitor navigate the current term and build an object of type T. Such an object is then returned as a result by this method.
Applies a Substitution to the current object, producing a new instance of T which differs from the current object because variables are replaced by their values, according to the binding carried by substitution.
Applies one or more Substitutions to the current object, producing a new instance of T which differs from the current one because variables are replaced by their values, according to the binding carried by the provided substitutions.
Casts the current Term to EmptyBlock, if possible, or returns null otherwise
Casts the current Term to EmptyBlock, if possible
Checks whether another term is equals to the current one or not, by explicitly letting the client decide whether to rely or not on Varriables complete names for checking equality among two Variables. If useVarCompleteName is true, Variables are compared through their Var.completeName property. Otherwise, they are compared through their Var.name property. Other sorts of terms are compared as Term.equals(Any?).
Returns a fresh variable, sharing this one's name but a newly minted, distinct completeName. Used, in particular, when a Term containing this variable is refreshed via Term.freshCopy.
Returns a fresh copy of this object, similarly to freshCopy(), possibly reusing variables from the provided scope, if any
This is an alias for apply aimed at supporting a square-brackets syntax for substitutions applications in Kotlin programs. It lets programmers write object[substitution] instead of object.apply(substitution). It applies one or more Substitutions to the current object, producing a new Term which differs from the current one because variables are replaced by their values, according to the binding carried by the provided substitutions.
Checks whether another term is structurally equals to the current one or not. Structural equivalence is a looser type of equivalence (w.r.t. term equivalence) where: