def substitute(self, mapping):
next_terms = iter([self._root])<EOL>output_stack = []<EOL>current_type = None<EOL>terms = []<EOL>variables = []<EOL>term = None<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>term = next(next_terms)<EOL><DEDENT>except StopIteration:<EOL><INDENT>term = None<EOL><DEDENT>if term is None:<EOL><INDENT>if current_type is None:<EOL><INDENT>term = terms[<NUM_LIT:0>]<EOL>break<EOL><DEDENT>else:<EOL><INDENT>if len(terms) == <NUM_LIT:0>:<EOL><INDENT>if current_type == And:<EOL><INDENT>term = True<EOL><DEDENT>elif current_type == Or:<EOL><INDENT>term = False<EOL><DEDENT><DEDENT>elif len(terms) == <NUM_LIT:1>:<EOL><INDENT>term = terms[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>term = current_type(*terms)<EOL><DEDENT><DEDENT>current_type, next_terms, terms = output_stack.pop()<EOL><DEDENT>else:<EOL><INDENT>if isinstance(term, _OperatorTerm):<EOL><INDENT>output_stack.append((current_type, next_terms, terms))<EOL>current_type = term.__class__<EOL>terms = []<EOL>next_terms = iter(term)<EOL>continue<EOL><DEDENT><DEDENT>if isinstance(term, Variable):<EOL><INDENT>term = mapping(term)<EOL>if not isinstance(term, (_OperatorTerm, Variable, bool)):<EOL><INDENT>raise SubstitutionError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(term))<EOL><DEDENT><DEDENT>if isinstance(term, Variable):<EOL><INDENT>variables.append(term)<EOL><DEDENT>while isinstance(term, bool):<EOL><INDENT>if current_type == And:<EOL><INDENT>if not term:<EOL><INDENT>current_type, next_terms, terms = output_stack.pop()<EOL>continue<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>elif current_type == Or:<EOL><INDENT>if term:<EOL><INDENT>current_type, next_terms, terms = output_stack.pop()<EOL>continue<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>terms.append(term)<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>terms.append(term)<EOL><DEDENT><DEDENT>return self.__class__(term, _vars=variables)<EOL>
Substitute variables using mapping function.