code: def get_logical_form(self,
                           action_sequence: List[str],
                           add_var_function: bool = True) -> str:
          
          # Basic outline: we assume that the bracketing that we get in the RHS of each action is the
          # correct bracketing for reconstructing the logical form.  This is true when there is no
          # currying in the action sequence.  Given this assumption, we just need to construct a tree
          # from the action sequence, then output all of the leaves in the tree, with brackets around
          # the children of all non-terminal nodes.
  
          remaining_actions = [action.split(" -> ") for action in action_sequence]
          tree = Tree(remaining_actions[0][1], [])
  
          try:
              remaining_actions = self._construct_node_from_actions(tree,
                                                                    remaining_actions[1:],
                                                                    add_var_function)
          except ParsingError:
              logger.error("Error parsing action sequence: %s", action_sequence)
              raise
  
          if remaining_actions:
              logger.error("Error parsing action sequence: %s", action_sequence)
              logger.error("Remaining actions were: %s", remaining_actions)
              raise ParsingError("Extra actions in action sequence")
          return nltk_tree_to_logical_form(tree)
docs: Takes an action sequence and constructs a logical form from it. This is useful if you want
          to get a logical form from a decoded sequence of actions generated by a transition based
          semantic parser.
  
          Parameters
          ----------
          action_sequence : ``List[str]``
              The sequence of actions as strings (eg.: ``['{START_SYMBOL} -> t', 't -> <e,t>', ...]``).
          add_var_function : ``bool`` (optional)
               ``var`` is a special function that some languages use within lambda functions to
               indicate the use of a variable (eg.: ``(lambda x (fb:row.row.year (var x)))``). Due to
               the way constrained decoding is currently implemented, it is easier for the decoder to
               not produce these functions. In that case, setting this flag adds the function in the
               logical form even though it is not present in the action sequence.