PT_Tree PT_findTreeParentRecursive(PT_Tree needle, PT_Tree haystack) { assert(needle != NULL); assert(haystack != NULL); assert(needle != haystack); if (ATtableGet(findParentCache, PT_TreeToTerm(haystack)) != NULL) { return NULL; } if (PT_hasTreeArgs(haystack)) { PT_Args children = PT_getTreeArgs(haystack); while (!PT_isArgsEmpty(children)) { PT_Tree child = PT_getArgsHead(children); if (PT_isEqualTree(child, needle)) { return haystack; } else { PT_Tree suspect = PT_findTreeParentRecursive(needle, child); if (suspect != NULL) { return suspect; } } children = PT_getArgsTail(children); } } ATtablePut(findParentCache, PT_TreeToTerm(haystack), PT_TreeToTerm(NeedleNotHere)); return NULL; }
ATbool PT_containsTreeCycle(PT_Tree tree) { if (PT_isTreeCycle(tree)) { return ATtrue; } if (PT_hasTreeArgs(tree)) { return PT_containsArgsCycle(PT_getTreeArgs(tree)); } return ATfalse; }
static PT_Tree pTreeWithSymbol(PT_Tree tree, int *i, PT_Symbol sym, SDF_Symbol ssym) { if (PT_isSymbolSort(sym)) { return pTree(tree, i); } else if (PT_isSymbolLit(sym)) { return tree; } else if (PT_isSymbolIterStar(sym) || PT_isSymbolIterPlus(sym)) { return pList(tree, i, ssym); } else if (PT_isSymbolIterStarSep(sym) || PT_isSymbolIterPlusSep(sym)) { return pSepList(tree, i, ssym); } /* the rest is handled by doing nothing */ if (PT_hasTreeArgs(tree)) { return PT_setTreeArgs(tree, pArgs(PT_getTreeArgs(tree), i)); } else { return tree; } }