

The function "popn" the items, in this case, the signature is "def
   popn(self, n: int) -> List[TensorVariable]:" this hints at an
   underlying contract - we are returning "TensorVariables". If we
   take a closer look at "sybmolic_convert.py" and
   "InstructionTranslatorBase"/"InstructionTranslator"we see that the
   only thing pushed onto and popped from our stack are
   "VariableTracker"s.


The function calls "VariableTracker.propagate". This takes the
   guards from every single item popped off the stack in 2, and
   recursively traverses it and combines all the guards into
   "options": "py  return {      "guards": guards,  }"


The function then makes a new instance of a "VariableTracker",
   "TupleVariable"out of the "items" and "options". This then allows
   us to install all the appropriate guards from the "items" that make
   up the new "TupleVariable"


Note:
Where did the first guards come from? Propagation is a good
  technique, but we need something created before it can be