eval_20(_Eq, _RetType, _Depth, _Self, ['sealed', InputVarList, Expr], Result) :- !, omit_atoms(InputVarList,OutputVarList), check_replace_with_local_var(OutputVarList, Expr, Result). % omit_atoms(+input variables, -variables less atoms) % If there are already bound values passed to sealed, no need for replacement omit_atoms([], []). omit_atoms([Head|Tail], Result) :- atomic(Head), !, omit_atoms(Tail, Result). omit_atoms([Head|Tail], [Head|Result]) :- omit_atoms(Tail, Result). % check_replace_with_local_var(+Sealed-Variables, +Expression, -NewExpression) % Boundary case -- no remaining variables to process, just return expression. check_replace_with_local_var([], Expr, Result) :- Result = Expr. % General case -- replace sealed variable with a new variable check_replace_with_local_var([VarHead|VarTail], Expr, Result) :- % '_' gives us a prolog variable replace_by_value(VarHead,Replacement), subst_same(Expr, VarHead, Replacement, NewExpr), check_replace_with_local_var(VarTail, NewExpr, Result). % change the variable into an new anonymous one (but copy attributes) replace_by_value(Var,Replacement):- var(Var),!,copy_term(Var,Replacement). % creates a deep copy that allows caller to destructively change it replace_by_value(Var,Replacement):- duplicate_term(Var,Replacement). %! subst_same(+Term, +OldTerm, +NewTerm, -ResultTerm) is det. % % Recursively substitutes occurrences of OldTerm with NewTerm within a Prolog term (Term), % producing a new term (ResultTerm). This predicate handles both simple and compound terms, including lists. % Note: Matching is done with the SWI same_term predicate which states that terms are equal if the % condition "the same variable, equivalent atomic data or a compound term allocated at the same address" % If the current term (Term) exactly matches OldTerm (with above criteria). subst_same(Term, OldTerm, NewTerm, NewTerm) :- same_term(OldTerm, Term), !. % If the current term is not a compound term (like an atom, number or the wrong variable) it stays the same subst_same(Term, _, _, Term) :- \+ compound(Term), !. % If the current term is a list, it processes each element of the list recursively. subst_same([Old|Structure], OldTerm, NewTerm, [New|StructureO]) :- !, subst_same(Old, OldTerm, NewTerm, New), subst_same(Structure, OldTerm, NewTerm, StructureO). % Compound Terms are decomposed and reconstructed with the possibly modified arguments. subst_same(OldStructure, OldTerm, NewTerm, NewStructure) :- OldStructure =.. [Functor|Args], subst_same(Args, OldTerm, NewTerm, NewArgs), NewStructure =.. [Functor|NewArgs]. % ================================================================= % ================================================================= % ================================================================= % SPACE EDITING % =================================================================