# #include "term.h"

This page has information from files term.h and term.c.

## Contents

- Public Routines
- Public Definitions
- Introduction

## Public Routines in File term.c

#### Index

all_args_vars | get_rigid_term | plist_of_subterms | term1
arg_position | get_rigid_term_dangerously | position_of_subterm | term2
args_distinct_vars | get_rigid_term_like | position_of_term_in_tlist | term_at_pos
biggest_variable | get_variable_term | renum_vars_recurse | term_depth
build_binary_term | greatest_symnum_in_term | same_structure | term_ident
build_binary_term_safe | greatest_variable | set_of_ivariables | term_set_variables
build_unary_term | ground_term | set_of_ivars | term_symbol
build_unary_term_safe | hash_term | set_of_variables | term_to_int
check_upward_term_links | int_to_term | set_of_vars | tlist_member
contains_skolem_function | is_constant | set_vars_recurse | tlist_set
contains_skolem_term | is_term | skolem_term | tlist_subset
copy_plist_of_terms | multiset_of_vars | sprint_term | upward_term_links
copy_term | multiset_vars | subst_term | variables_multisubset
eq_term | nat_to_term | subst_var_term | variables_subset
fprint_term | natural_constant_term | symbol_count | zap_plist_of_terms
fprint_term_mem | occurrences | symbol_in_term | zap_term
free_term | occurs_in | symbol_occurrences |
free_vars_term | p_term | symbols_in_term |
fsym_set_in_term | p_term_mem | term0 |

#### Details

    BOOL all_args_vars(Term t);

This Boolean routine checks if all argumets of Term t are VARIABLEs. (It is true also if t is a VARIABLE.)

    int arg_position(Term parent, Term child);

If the given terms are in a parent-child relatioship, return the argument position (index) of the child. Otherwise, return -1.

    BOOL args_distinct_vars(Term t);

Is the Term a nonvariable with distinct variables as arguments? (Constants satisfy this.)

    int biggest_variable(Term t);

This routine returns the greatest variable index of any variable int the given term t. If t is ground, -1 is returned.

    Term build_binary_term(int sn, Term a1, Term a2);

Build and return a binary term with SYMNUM sn, first term a1, and second term a2.

WARNING: if sn is not a binary symbol, bad things will happen!

    Term build_binary_term_safe(char *str, Term a1, Term a2);

Build and return a binary term with root str, first term a1, and second term a2.

If you know the symnum, and you're certain it has arity 2, you can use the faster routine build_binary_term() instead;

    Term build_unary_term(int sn, Term a);

Build and return a unary term with SYMNUM sn and argument term a.

WARNING: if sn is not a unary symbol, bad things will happen!

    Term build_unary_term_safe(char *str, Term a);

Build and return a unary term with root str, argument a.

If you know the symnum, and you're certain it has arity 1, you can use the faster routine build_unary_term() instead;

    BOOL check_upward_term_links(Term t, void *p);

In the given Term t, check that the "container" field of t and each subterm, except variables, point to (void *) p.

    BOOL contains_skolem_function(Term t);

    BOOL contains_skolem_term(Term t);

    Plist copy_plist_of_terms(Plist terms);

    Term copy_term(Term t);

This routine copies a term. Only the symbols and structure are copied---any extra fields such as bits or u are NOT copied.

    BOOL eq_term(Term a);

This function checks if an atom is an equality atom (positive or negative) for the purposes of paramodulation and demodulation.

    void fprint_term(FILE *fp, Term t);

This routine prints (to FILE *fp) a term. A newline is NOT printed.

    void fprint_term_mem(FILE *fp, BOOL heading);

This routine prints (to FILE *fp) memory usage statistics for Terms. The Boolean argument heading tells whether to print a heading on the table.

    void free_term(Term p);

This routine frees a term node only. To recursively free all of the subterms as well, call zap_term(t) instead.

    Plist free_vars_term(Term t, Plist vars);

Return the set of constants that look like variables. The terms are newly constructed; if they are not used, the list should be deallocated with zap_tlist().

    Ilist fsym_set_in_term(Term t);

    Term get_rigid_term(char *sym, int arity);

This routine allocates and returns a term node with the given symbol and arity. If you already have a similar term node, say t, (containing the symbol and arity you need) call get_rigid_term_like(t) instead.

    Term get_rigid_term_dangerously(int symnum, int arity);

This routine can be used to allocate a term node if all you have is the symbol ID and arity. If the arity is not correct for the symbol ID, terrible things will happen!

If you have a similar term, use get_rigid_term_like() instead. If you can afford the time to access the symbol table, use sn_to_str() and get_rigid_term() instead.

    Term get_rigid_term_like(Term t);

This routine allocates and returns a term node with the same symbol and arity as the given Term t.

    Term get_variable_term(int var_num);

This routine returns a term of type VARIABLE. The index of the variable is set to var_num, which should be an integer >= 0.

    int greatest_symnum_in_term(Term t);

This function returns the greatest SYMNUM (of a CONSTANT or COMPLEX term) in the given Term t. If the term is a VARIABLE, return -1.

    int greatest_variable(Term t);

This routine returns the greatest variable index in a term. If the term is ground, -1 is returned.

    BOOL ground_term(Term t);

This function checks if a term is ground, that is, has no variables.

    unsigned hash_term(Term t);

    Term int_to_term(int i);

This routine takes an integer and returns the Term representation.

    BOOL is_constant(Term t, char *str);

Is term t a specific constant?

    BOOL is_term(Term t, char *str, int arity);

Does term t have the the given symbol and arity?

    I2list multiset_of_vars(Term t, I2list vars);

    I2list multiset_vars(Term t);

    Term nat_to_term(int n);

This routine takes a nonnegative integer and returns a constant Term with the string representation of the integer as the constant symbol.

    int natural_constant_term(Term t);

This routine takes a term, and if the term represents an nonnegative integer, that integer is returned; otherwise, -1 is returned.

    int occurrences(Term t, Term target);

This function returns the number of occurrences of Term target in Term t. The checks are made with term_ident().

    BOOL occurs_in(Term t1, Term t2);

This function checks if Term t2 is identical to a subterm of Term t1, including the case term_ident(t1,t2). All identity checks are done with term_ident(), so extra fields such as bits or u are not checked.

    void p_term(Term t);

This routine prints a term, followed by '\n' and fflush, to stdout. If you don't want the newline, use fprint_term() instead. If you want the term put into a string, use sprint_term() instead.

    void p_term_mem(void);

This routine prints memory usage statistics for Terms to stdout.

    Plist plist_of_subterms(Term t);

    Ilist position_of_subterm(Term t, Term subterm);

    int position_of_term_in_tlist(Term t, Plist lst);

    Term renum_vars_recurse(Term t, int vmap[], int max_vars);

This routine renumbers the variables of a term. It is assumed that vmap has been filled with -1 on the initial call and that the size of vmap is at least max_vars.

This returns a Term instead of being void, in case the given term is itself a variable. (Recall that variables may be shared, so we can't just change a variable's index.

    BOOL same_structure(Term a, Term b);

If variables are ignored, are the terms identical?

    Ilist set_of_ivariables(Term t);

Given a Term, return the set of integers corresponding to its variables.

    Ilist set_of_ivars(Term t, Ilist ivars);

See set_of_ivariables(t).

    Plist set_of_variables(Term t);

Given a Term, return the set of variables.

    Plist set_of_vars(Term t, Plist vars);

See set_of_variables(t).

    Term set_vars_recurse(Term t, char *vnames[], int max_vars);

This routine sets the variables of a term. It is assumed that vnames has been filled with NULL on the initial call and that the size of vnames is at least max_vars.

This returns a Term instead of being void, in case the given term is itself becomes a variable.

    BOOL skolem_term(Term t);

    void sprint_term(String_buf sb, Term t);

This (recursive) routine appends the string representation of a term to a String_buf. A newline is not included.

    Term subst_term(Term t, Term target, Term replacement);

In term t, replace all occurrences of Term target with copies of Term replacement. Free all of the replaced terms;

    Term subst_var_term(Term t, int symnum, int varnum);

In Term t, replace all CONSTANT terms containing SYMNUM symnum with a variable containing VARNUM varnum. Free the replaced constants and return the result.

    int symbol_count(Term t);

This routine returns the total number of symbols (i.e., the number of nodes) in the given term t.

    BOOL symbol_in_term(int symnum, Term t);

    int symbol_occurrences(Term t, int symnum);

Return the number of occurrences of a symbol in a term.

    I2list symbols_in_term(Term t, I2list g);

This routine collects the multiset of nonvariable symbols in a term. An Ilist of symbol IDs (symnums) is returned

    Term term0(char *sym);

Build constant Term.

    Term term1(char *sym, Term arg);

Build a unary term. The argument Term is not copied.

    Term term2(char *sym, Term arg1, Term arg2);

Build a binary term. The argument Terms are not copied.

    Term term_at_pos(Term t, Ilist pos);

    int term_depth(Term t);

Return the depth of a term. Variables and constants have depth 0.

    BOOL term_ident(Term t1, Term t2);

This function checks if two terms are identical. Only the structure and symbols are checked---any extra fields such as bits or u are NOT checked.

    void term_set_variables(Term t, int max_vars);

This routine traverses a term and changes the constants that should be variables, into variables. On input, the term should have no variables. The new variables are numbered 0, 1, 2 ... according the the first occurrence, reading from the left.

A fatal error occurs if there are more than max_vars variables.

If you are dealing with clauses, use clause_set_variables() instead.

    char *term_symbol(Term t);

Return the print string associated with the given nonvariable term. If the term is a variable, return NULL.

    BOOL term_to_int(Term t, int *result);

Given a term, see if it represents an integer. If so, set *result to the integer and return TRUE. If not, return FALSE.

The term representation of a negative integer is the function symbol "-" applied to a nonnegative integer.

    BOOL tlist_member(Term t, Plist lst);

This function checks if a term is a member of a Plist. The function term_ident(t1,t2) is used.

    BOOL tlist_set(Plist a);

    BOOL tlist_subset(Plist a, Plist b);

    void upward_term_links(Term t, void *p);

In the given Term t, make the "container" field of t and each subterm, except variables, point to (void *) p.

    BOOL variables_multisubset(Term a, Term b);

    BOOL variables_subset(Term t1, Term t2);

    void zap_plist_of_terms(Plist lst);

Free a Plist of terms.

    void zap_term(Term t);

This routine frees a term t and all of its subterms. You should not refer to t after calling zap_term(t).

## Public Definitions in File term.h

    #define MAX_VARS  100   /* max number of (distinct) variables per term */
    #define MAX_VNUM  5000  /* maximum variable ID, for array of vars */

    #define MAX_VAR   INT_MAX     /* max var ID that fits in sym field of term */
    #define MAX_SYM   INT_MAX     /* max ID of any rigid symbol */
    #define MAX_ARITY UCHAR_MAX   /* max arity of any term (don't make this big) */

    #define FLAGS_TYPE unsigned char  /* for private_flags field of Term */

    typedef struct term * Term;     /* Term is a pointer to a term struct */

    struct term {
      int            private_symbol; /* const/func/pred/var symbol ID */
      unsigned char  arity;          /* number of auguments */
      FLAGS_TYPE     private_flags;  /* for marking terms in various ways */
      Term           *args;          /* array (size arity) of pointers to args */
      void           *container;     /* containing object */
      union {
        unsigned     id;             /* unique ID, probably for FPA indexing */
        void         *vp;            /* auxiliary pointer */
      } u;
    };

    /* to check type of term */
    #define VARIABLE(t) ((t)->private_symbol >= 0)
    #define CONSTANT(t) ((t)->private_symbol < 0 && (t)->arity == 0)
    #define COMPLEX(t)  ((t)->private_symbol < 0 && (t)->arity > 0)

    /* to get symbol ID from a CONSTANT or COMPLEX term */
    #define SYMNUM(t)   (-((t)->private_symbol))

    /* to get the variable number of a VARIABLE term */
    #define VARNUM(t)   ((t)->private_symbol)

    /* to get the arity of a term (VARIABLE terms have arity 0) */
    #define ARITY(t)    ((t)->arity)

    /* to get the i-th argument of a term (make sure i is in [0..arity-1]) */
    #define ARG(t,i)    ((t)->args[i])

    /* to get the array of arguments */
    #define ARGS(t)    ((t)->args)

## Introduction

The Term data structure is designed mainly to represent first-order untyped terms. It is generally used for atoms as well, because the indexing and unification methods don't care whether an object is a term or an atom.

No term structure sharing is supported at this level of abstraction. (Higher-level packagers can build terms with shared structure if they wish.) Because we envision applications with tens of millions of terms, small size for the individual nodes is important. So we have some overloaded fields, and macros are provided to get some of the information from from term nodes.

There are three types of term, and the Boolean macros `VARIABLE(t)`, `CONSTANT(t)`, and `COMPLEX(t)` should be used to find out what type a term is. If you have a `CONSTANT` or `COMPLEX` term t, you can get its symbol id with `SYMNUM(t)` (from which you can get other information about the symbol such as the print string and any special properties). If you have a variable t, you can get its index with `VARNUM(t)`, which is a signed integral type in the range [0..`MAX_VAR`]. Warning: `MAX_VAR` is a big number---a higher-level unification package will typically have a much smaller `MAX_VARS` defined for array sizes, because it does array indexing with `VARNUM(t)`.

The macro `ARITY(t)` gets the arity of a term (constants and variables have arity 0), and `ARG(t,i)` gets the i-th argument (counting from 0) of a term. When using `ARG(t,i)`, make sure that i is in range [0..`ARITY(t)`-1], because `ARG` does not check.

Here is an example of recursing through a term.

    int symbol_count(Term t)
    {
      int count = 0;
      int i;
      for (i = 0; i < ARITY(t); i++)
        count += symbol_count(ARG(t,i));
      return count+1;
    }