library(terms)
This library module provides miscellaneous operations on terms. Exported predicates:
subsumeschk(
+General,
+Specific)
This predicate is identical to the built-in subsumes_term/2
and it is only present for backwards compatibility.
subsumes(
+General,
+Specific)
In many cases, binding variable is not really desirable, in which case
subsumes_term/2
should be used instead.
If unification is in fact wanted, it may be better to make this explicit in your code by
using subsumes_term/2
followed by an explicit unification, e.g. subsumes_term(G,S), G=S
.
variant(
+Term,
+Variant)
term_subsumer(
+Term1,
+Term2,
-Term)
term_hash(
+Term,
-Hash)
term_hash(Term, [], Hash)
.
term_hash(
+Term,
+Options,
-Hash)
algorithm(
Algorithm)
default
jenkins
. This is the
default. If we ever see a need to change the default hash
algorithm again then the algorithm denoted by default
may
change but the algorithm denoted by the other names, like
'sicstus-4.0.5'
, will not change.
jenkins
hsieh
term_hash/3
.
sdbm
'sicstus-4.0.4'
This algorithm produces hash values that may differ
between platforms.
'sicstus-4.0.5'
jenkins
. I.e. the default since
SICStus Prolog 4.0.5. Note that this atom needs to be quoted.
there are some other (not as good) algorithms available for the curious, see the source for detail.
Unless otherwise noted, the hash value will be identical across
runs and platforms.
range(
Range)
infinite
smallint
2^28
on 32-bit platforms and
2^60
on 64-bit platforms.
smallint32
2^28
.
default
smallint32
. This is the default. This ensures
that, by default, the same hash value is computed for the same
term on both 32-bit and 64-bit platforms.
depth(
Depth)
Depth
is a non-negative integer the subterms up to depth
Depth of Term are used in the
computation. Alternatively, if Depth
is the atom
infinite
, all subterms of Term are relevant in
computing Hash. In the latter case Term must be
acyclic.
In this context the depth of a term is defined as
follows: the (principal functor of) the term itself
has depth 1, and an argument of a term with depth
i has depth i+1. Note that this is similar to, but not
the same as, the value computed by term_depth/2
.
For legacy reasons a Depth of -1 is treated the same a
infinite
.
if_var(
IfVar)
error
ignore
value(Value)
Hash
is bound to Value
. There is no
restrictions on Value
, it need not be an integer or even be
ground.
default
value(_)
, i.e. term_hash/3
just succeeds without binding Hash
. This is the default.
This is useful when the hash value us used for first-argument
indexing. This ensures that if the (possibly variable-valued) hash
values for Term1 and Term2 are Hash1 and
Hash2, respectively, then if Term1 and Term2 are
unifiable (to the specified depth) then so are Hash1 and
Hash2.
For other use cases it is probably more appropriate to specify
if_var(error)
.
term_hash(
+Term,
+Depth,
+Range,
-Hash)
term_hash(Term, [depth(
Depth), range(
Range)], Hash)
.
term_hash/[2,3,4]
is provided primarily as a tool for the
construction of sophisticated Prolog clause access schemes. Its
intended use is to generate hash values for terms that will be
used with first argument clause indexing, yielding compact and
efficient multi-argument or deep argument indexing. Note that, for
this usage, it is very important that the hash value is a
small integer, as it will be by default.
term_variables_set(
+Term,
-Variables)
since release 4.3This was called term_variables/2
prior to SICStus Prolog
4.3 but now term_variables/2
is a built-in with different
meaning, due to alignment with the ISO Prolog standard.
term_variables_bag(
+Term,
-Variables)
This predicate has been superseeded by the built-in
term_variables/2
and it is only present for backwards compatibility.
The name is an historical accident, the result is not really a bag (i.e. multiset).
cyclic_term(
+X)
term_order(
+X,
+Y,
-R)
<
, =
, or >
according
as X @< Y, X == Y, or X @> Y. This is the same as compare/3
, except
for the argument order.
contains_term(
+Kernel,
+Expression)
sub_term/2
.
free_of_term(
+Kernel,
+Expression)
occurrences_of_term(
+Kernel,
+Expression,
-Tally)
sub_term/2
and then
test them with this routine. If you just want to find out
whether Kernel occurs in Expression or not, use contains_term/2
or free_of_term/2
.
contains_var(
+Variable,
+Term)
==
to check for
the variable (contains_term/2
uses =
) so it can be used to check
for arbitrary terms, not just variables.
free_of_var(
+Variable,
+Term)
occurrences_of_var(
+Term,
+Variable,
-Tally)
sub_term/2
and then
test them with this routine. If you just want to find out
whether Variable occurs in Term or not, use contains_var/2
or free_of_var/2
.
sub_term(
?Kernel,
+Term)
depth_bound(
+Term,
+Bound)
term_depth/2
.
length_bound(
?List,
+Bound)
size_bound(
+Term,
+Bound)
term_size/2
.
term_depth(
+Term,
-Depth)
term_depth(Var) = 0 term_depth(Const) = 0 term_depth(F(T1,...,Tn)) = 1+max(term_depth(T1),...,term_depth(Tn))
Could be defined as:
term_depth(X, Depth) :- simple(X), !, Depth = 0. term_depth(X, Depth) :- ( foreacharg(A,X), fromto(0,D0,D,Depth0) do term_depth(A, D1), D is max(D0,D1) ), Depth is Depth0+1.
term_size(
+Term,
-Size)
term_size(X, Size) :- var(X), !, Size = 0. term_size(X, Size) :- simple(X), !, Size = 1. term_size(X, Size) :- ( foreacharg(A,X), fromto(1,S0,S,Size) do term_size(A, S1), S is S0+S1 ).
same_functor(
?T1,
?T2)
same_functor(
?T1,
?T2,
?N)
same_functor/3
, at least one of T1 and T2
must be bound, or an error will be reported.
same_functor(
?T1,
?T2,
?F,
?N)