12.4.6 Unifying data
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
      • Foreign Language Interface
        • The Foreign Include File
          • Unifying data
            • PL_unify()
            • PL_unify_atom()
            • PL_unify_bool()
            • PL_unify_chars()
            • PL_unify_atom_chars()
            • PL_unify_list_chars()
            • PL_unify_string_chars()
            • PL_unify_integer()
            • PL_unify_int64()
            • PL_unify_uint64()
            • PL_unify_float()
            • PL_unify_pointer()
            • PL_unify_functor()
            • PL_unify_compound()
            • PL_unify_list()
            • PL_unify_nil()
            • PL_unify_arg()
            • PL_unify_term()
            • PL_chars_to_term()
            • PL_wchars_to_term()
            • PL_quote()
            • PL_for_dict()
    • Packages
Availability:C-language interface function
bool PL_unify_list(term_t ?l, term_t -h, term_t -t)
Unify l with a list-cell (./2). If successful, write a reference to the head of the list into h and a reference to the tail of the list into t. This reference to h may be used for subsequent calls to this function. Suppose we want to return a list of atoms from a char **. We could use the example described by PL_cons_list(), followed by a call to PL_unify(), or we can use the code below. If the predicate argument is unbound, the difference is minimal (the code based on PL_cons_list() is probably slightly faster). If the argument is bound, the code below may fail before reaching the end of the word list, but even if the unification succeeds, this code avoids a duplicate (garbage) list and a deep unification.

Note that PL_unify_list() is not used with env but with tail, which is a copy of env. PL_copy_term_ref() creates a copy term_t holding the same Prolog term, i.e., not a copy of the Prolog term. The only thing that is allowed to be done with an argument to a foreign predicate (such as env) is unification; for anything that might over-write the term, you must use a copy created by PL_copy_term_ref(). The name PL_unify_list() is slightly misleading - it unifies the first argument (l but overwrites the second (h) and third (t) arguments.

foreign_t
pl_get_environ(term_t env)
{ term_t tail = PL_copy_term_ref(env);
  term_t item = PL_new_term_ref();
  extern char **environ;

  for(const char **e = environ; *e; e++)
  { if ( !PL_unify_list(tail, item, tail) ||
         !PL_unify_atom_chars(item, *e) )
      PL_fail;
  }

  return PL_unify_nil(tail);
}

In this example, item is initialized outside the loop. This allocates a single new reference to a term, which is used as a temporary inside the loop - there is no need to allocate a new reference each time around the loop because the item term reference can be reused and the call to PL_unify_list() copies a reference to the new list cell's head into the the term referenced by item.