lojix/logic/src/main/com/thesett/aima/logic/fol/TermUtils.java
public static <T extends Term> List<T> flattenTerm(Term term, Class<T> superClass, String symbolToFlattenOn,
        VariableAndFunctorInterner interner) throws SourceCodeException
    {
        List<T> terms = new LinkedList<T>();

        // Used to hold the next term to examine as operators are flattened.
        Term nextTerm = term;

        // Used to indicate when there are no more operators to flatten.
        boolean mayBeMoreCommas = true;

        // Get the functor name of the symbol to flatten on.
        int symbolName = interner.internFunctorName(symbolToFlattenOn, 2);

        // Walk down the terms matching symbols and flattening them into a list of terms.
        while (mayBeMoreCommas)
        {
            if (!nextTerm.isBracketed() && (nextTerm instanceof Functor) &&
                    (symbolName == (((Functor) nextTerm).getName())))
            {
                Functor op = (Functor) nextTerm;
                Term termToExtract = op.getArgument(0);

                if (superClass.isInstance(termToExtract))
                {
                    terms.add(superClass.cast(termToExtract));
                    nextTerm = op.getArgument(1);
                }
                else
                {
                    throw new SourceCodeException("The term " + termToExtract + " is expected to extend " + superClass +
                        " but does not.", null, null, null, termToExtract.getSourceCodePosition());
                }
            }
            else
            {
                if (superClass.isInstance(nextTerm))
                {
                    terms.add(superClass.cast(nextTerm));
                    mayBeMoreCommas = false;
                }
                else
                {
                    throw new SourceCodeException("The term " + nextTerm + " is expected to extend " + superClass +
                        " but does not.", null, null, null, nextTerm.getSourceCodePosition());
                }
            }
        }

        return terms;
    }
public static <T extends Term> List<T> flattenTerm(Term term, Class<T> superClass, String symbolToFlattenOn,
        VariableAndFunctorInterner interner) throws SourceCodeException
    {
        List<T> terms = new LinkedList<T>();

        // Used to hold the next term to examine as operators are flattened.
        Term nextTerm = term;

        // Used to indicate when there are no more operators to flatten.
        boolean mayBeMoreCommas = true;

        // Get the functor name of the symbol to flatten on.
        int symbolName = interner.internFunctorName(symbolToFlattenOn, 2);

        // Walk down the terms matching symbols and flattening them into a list of terms.
        while (mayBeMoreCommas)
        {
            if (!nextTerm.isBracketed() && (nextTerm instanceof Functor) &&
                    (symbolName == (((Functor) nextTerm).getName())))
            {
                Functor op = (Functor) nextTerm;
                Term termToExtract = op.getArgument(0);

                if (superClass.isInstance(termToExtract))
                {
                    terms.add(superClass.cast(termToExtract));
                    nextTerm = op.getArgument(1);
                }
                else
                {
                    throw new SourceCodeException("The term " + termToExtract + " is expected to extend " + superClass +
                        " but does not.", null, null, null, termToExtract.getSourceCodePosition());
                }
            }
            else
            {
                if (superClass.isInstance(nextTerm))
                {
                    terms.add(superClass.cast(nextTerm));
                    mayBeMoreCommas = false;
                }
                else
                {
                    throw new SourceCodeException("The term " + nextTerm + " is expected to extend " + superClass +
                        " but does not.", null, null, null, nextTerm.getSourceCodePosition());
                }
            }
        }

        return terms;
    }
Flattens a sequence of terms as a symbol seperated argument list. Terms that have been parsed as a bracketed
expressions will not be flattened. All of the terms in the list must sub sub-classes of a specified super class.
This is usefull, for example, when parsing a sequence of functors in a clause body, in order to check that all of
the body members really are functors and not just terms.

<p/>For example, 'a, b, c' is broken into the list { a, b, c } on the symbol ','. The example, 'a, (b, c), d' is
broken into the list { a, (b, c), d} on the symbol ',' and so on.

@param  <T>               The type of the class that all flattened terms must extend.
@param  term              The term to flatten.
@param  superClass        The root class that all flattened terms must extend.
@param  symbolToFlattenOn A symbol of fixity 2 to flatten on.
@param  interner          The functor and variable interner for the namespace the term to flatten is in.

@return A sequence of terms parsed as a term, then flattened back into a list seperated on commas.

@throws SourceCodeException If any of the extracted terms encountered do not extend the superclass.