# Path: misc.py
# def flipSide(side):
# def _interleave(a, xs):
# 
# Path: calculus/symbol.py
# class Symbol:
# class StringSymbol(Symbol):
#   def __init__(self, type):
#   def _generate_id(self):
#   def __eq__(self, other):
#   def __ne__(self):
#   def __hash__(self):
#   def __repr__(self):
#   def __init__(self, s, type, infix = None):
#   def __repr__(self):
# 
# Path: calculus/variable.py
# class Variable(GeneralizedVariable):
#   def __init__(self):
#     self._generate_id()
# 
#   def _generate_id(self):
#     global n_variables
#     self._id = n_variables
#     n_variables += 1
# 
#   def updateVariables(self):
#     return Variable()
# 
#   def __eq__(self, other):
#     return self.__class__ == other.__class__ and self._id == other._id
#   def __ne__(self, other):
#     return not(self == other)
#   def __hash__(self):
#     return hash(self._id)
# 
#   def applied_variables(self):
#     return Set([])
# 
#   def __repr__(self):
#     return "<abstract variable %s>"%(self._id,)
# 
#   def substituteVariable(self, a, b):
#     if self == a:
#       return b
#     else:
#       return self
# 
#   def freeVariables(self):
#     return Set([self])
# 
# Path: lib/common_symbols.py



from misc import left, right
from calculus import symbol
from calculus.variable import Variable
from lib import common_symbols
from sets import Set
    right_as_formula = self.right.as_formula()
    left_as_formula = self.left.as_formula()
    return (lambda x:
        nt_right(x).forwardCompose(nt_left(And(right_as_formula, x))).forwardCompose(
          endofunctor.onArrow(
            And( left_as_formula
               , And(right_as_formula, x)).forwardAssociateOther())))

def identity_dependent_arrow(formula):
  return DependentArrow(src = formula, tgt = formula,
      assumption = SingleAssumption(Always(true)),
      arrow = And(Always(true), formula).forwardForgetLeft())

class DependentArrow:
  # src, tgt: formulas
  # assumption: an Assumption instance.
  # arrow: an arrow: And(assumption.as_formula(), src) -> tgt
  def __init__(self, src, tgt, assumption, arrow):
    self.src = src
    self.tgt = tgt
    self.assumption = assumption
    self.arrow = arrow

  def dependent_arrow_not(self):
    src = Not(self.tgt)
    return DependentArrow(src = src, tgt = Not(self.src), assumption = self.assumption,
        arrow = And(self.assumption.as_formula(), src).forwardOnRightFollow(lambda x:
          x.forwardOnNot(self.arrow)).forwardApply())

  def always(self):

# Path: misc.py
# def flipSide(side):
# def _interleave(a, xs):
# 
# Path: calculus/symbol.py
# class Symbol:
# class StringSymbol(Symbol):
#   def __init__(self, type):
#   def _generate_id(self):
#   def __eq__(self, other):
#   def __ne__(self):
#   def __hash__(self):
#   def __repr__(self):
#   def __init__(self, s, type, infix = None):
#   def __repr__(self):
# 
# Path: calculus/variable.py
# class Variable(GeneralizedVariable):
#   def __init__(self):
#     self._generate_id()
# 
#   def _generate_id(self):
#     global n_variables
#     self._id = n_variables
#     n_variables += 1
# 
#   def updateVariables(self):
#     return Variable()
# 
#   def __eq__(self, other):
#     return self.__class__ == other.__class__ and self._id == other._id
#   def __ne__(self, other):
#     return not(self == other)
#   def __hash__(self):
#     return hash(self._id)
# 
#   def applied_variables(self):
#     return Set([])
# 
#   def __repr__(self):
#     return "<abstract variable %s>"%(self._id,)
# 
#   def substituteVariable(self, a, b):
#     if self == a:
#       return b
#     else:
#       return self
# 
#   def freeVariables(self):
#     return Set([self])
# 
# Path: lib/common_symbols.py



# Path: calculus/basic/formula.py
from misc import left, right
from calculus import symbol
from calculus.variable import Variable
from lib import common_symbols
from sets import Set

    right_as_formula = self.right.as_formula()
    left_as_formula = self.left.as_formula()
    return (lambda x:
        nt_right(x).forwardCompose(nt_left(And(right_as_formula, x))).forwardCompose(
          endofunctor.onArrow(
            And( left_as_formula
               , And(right_as_formula, x)).forwardAssociateOther())))

def identity_dependent_arrow(formula):
  return DependentArrow(src = formula, tgt = formula,
      assumption = SingleAssumption(Always(true)),
      arrow = And(Always(true), formula).forwardForgetLeft())

class DependentArrow:
  # src, tgt: formulas
  # assumption: an Assumption instance.
  # arrow: an arrow: And(assumption.as_formula(), src) -> tgt
  def __init__(self, src, tgt, assumption, arrow):
    self.src = src
    self.tgt = tgt
    self.assumption = assumption
    self.arrow = arrow

  def dependent_arrow_not(self):
    src = Not(self.tgt)
    return DependentArrow(src = src, tgt = Not(self.src), assumption = self.assumption,
        arrow = And(self.assumption.as_formula(), src).forwardOnRightFollow(lambda x:
          x.forwardOnNot(self.arrow)).forwardApply())

  def always(self):

    src = Always(self.src)