raw_match :
  hol_type list -> term set ->
  term -> term ->
  (term,term) subst * (hol_type,hol_type) subst ->
    ((term,term) subst * term set) *
    ((hol_type,hol_type) subst * hol_type list)aconv (subst TmS' (inst TyS pat)) ob.
The pair (tmS,tyS) is an accumulator argument. This allows raw_match to be folded through lists of terms to be matched. (TmS,TyS) must agree with (tmS,tyS). This means that if there is a {redex,residue} in TmS and also a {redex,residue} in tmS so that both redex fields are equal, then the residue fields must be alpha-convertible. Similarly for types: if there is a {redex,residue} in TyS and also a {redex,residue} in tyS so that both redex fields are equal, then the residue fields must also be equal. If these conditions hold, then the result-pair (TmS,TyS) includes (tmS,tyS).
Finally, note that the result also includes a set (resp. a list) of term and type variables, accompanying the substitutions. These represent identity bindings that have occurred in the process of doing the match. If raw_match is to be folded across multiple problems, these output values will need to be merged with avoid_tms and avoid_tys respectively on the next call so that they cannot be instantiated a second time. Because they are identity bindings, they do not need to be referred to in validating the central identity above.
   > val ((S,_),(T,_)) =
       raw_match [] empty_varset
                 (Term `\x:'a. x = f (y:'b)`)
                 (Term `\a.    a = ~p`) ([],[]);
   val S =
     [{redex = `(y :'b)`,       residue = `(p :bool)`},
      {redex = `(f :'b -> 'a)`, residue = `$~`}] : ...
   val T =
     [{redex = `:'b`, residue = `:bool`},
      {redex = `:'a`, residue = `:bool`}] : ...