def setUp(self):
     self.a = UnnamedOpetopicSet.Variable("a", UnnamedOpetope.Arrow())
     self.b = UnnamedOpetopicSet.Variable("b", UnnamedOpetope.Arrow())
     self.i1 = UnnamedOpetopicSet.Variable(
         "i1", UnnamedOpetope.OpetopicInteger(1))
     self.i2 = UnnamedOpetopicSet.Variable(
         "i2", UnnamedOpetope.OpetopicInteger(2))
     self.i3 = UnnamedOpetopicSet.Variable(
         "i3", UnnamedOpetope.OpetopicInteger(3))
     self.c = UnnamedOpetopicSet.Variable(
         "c",
         UnnamedOpetope.Graft(
             UnnamedOpetope.Shift(UnnamedOpetope.OpetopicInteger(2)),
             UnnamedOpetope.OpetopicInteger(2),
             UnnamedOpetope.Address.fromList([['*']], 2)))
Beispiel #2
0
 def test_OpetopicTree(self):
     self.assertEqual(
         UnnamedOpetope.OpetopicTree(None).eval(),
         UnnamedOpetope.Degen(UnnamedOpetope.Arrow()).eval())
     for i in range(5):
         self.assertEqual(
             UnnamedOpetope.OpetopicTree([None] * i).eval(),
             UnnamedOpetope.Shift(UnnamedOpetope.OpetopicInteger(i)).eval())
     for i in range(5):
         tree = [None] * i + [[None]] + [None] * (4 - i)
         self.assertEqual(
             UnnamedOpetope.OpetopicTree(tree).eval(),
             UnnamedOpetope.Graft(
                 UnnamedOpetope.Shift(UnnamedOpetope.OpetopicInteger(5)),
                 UnnamedOpetope.OpetopicInteger(1),
                 UnnamedOpetope.address([['*'] * i], 2)).eval())
def suniv(seq: UnnamedOpetopicSet.Sequent, suCellName: str, cellName: str,
          addr: UnnamedOpetope.Address, factorizationName: str,
          fillerName: str) -> UnnamedOpetopicSet.Sequent:
    """
    From

    * an address :math:`[p]` (argument ``addr``);
    * a cell :math:`\\alpha : \\forall_{[p]} \\mathbf{P} \\longrightarrow u`
      (with name ``suCellName``);
    * a cell :math:`\\beta : \\mathbf{P'} \\longrightarrow u` (with name
      ``cellName``), where :math:`\\mathbf{P'}` is :math:`\\mathbf{P}` except
      at address :math:`[p]` where it is :math:`s`;

    applies the source universal property of :math:`\\alpha` at :math:`[p]`
    over :math:`\\beta`, thus creating

    * a factorization cell :math:`\\xi : s \\longrightarrow \\mathsf{s}_{[p]}
      \\mathbf{P}`;
    * a filler :math:`A`, target universal, and source universal at
      :math:`\\xi`, i.e. at address :math:`[[p]]`.
    """

    # Inits
    alphatype = seq.context[suCellName].type
    betatype = seq.context[cellName].type
    P = alphatype.source
    Q = betatype.source
    u = alphatype.target

    # Checks & inits
    if seq.pastingDiagram is not None:
        raise DerivationError(
            "Apply source univ. prop.",
            "Sequent expected to not type a pasting diagram")
    elif u is None:
        raise RuntimeError("[Apply source univ. prop.] Source universal cell "
                           "{sucell} is a point. In valid derivations, this "
                           "should not happen".format(sucell=suCellName))
    elif P.nodes is None:
        raise DerivationError(
            "Apply source univ. prop.",
            "Source universal cell {sucell} cannot be degenerate",
            sucell=suCellName)
    elif Q.nodes is None:
        raise DerivationError("Apply source univ. prop.",
                              "Cell {cell} cannot be degenerate",
                              cell=cellName)
    elif addr not in P.nodes.keys():
        raise DerivationError("Apply source univ. prop.",
                              "Address {addr} not in source of {sucell}",
                              addr=addr,
                              sucell=suCellName)
    elif betatype.target != u:
        raise DerivationError(
            "Apply source univ. prop.",
            "Cells {sucell} and {cell} are not compatible: targets differ",
            cell=cellName,
            sucell=suCellName)
    elif P.nodes.keys() != Q.nodes.keys():
        raise DerivationError(
            "Apply source univ. prop.",
            "Cells {sucell} and {cell} are not compatible: source pasting "
            "diagrams do not have the same addresses",
            cell=cellName,
            sucell=suCellName)
    for a in P.nodes.keys():
        if a != addr and P.nodes[a] != Q.nodes[a]:
            raise DerivationError(
                "Apply source univ. prop.",
                "Cells {sucell} and {cell} are not compatible: source pasting "
                "diagrams do not agree on address {a}",
                cell=cellName,
                sucell=suCellName,
                a=a)

    # Derive xi
    xishapeproof = seq.context[Q.source(addr)].type.source.shapeProof
    res = UnnamedOpetopicSet.graft(
        seq,
        UnnamedOpetopicSet.pastingDiagram(UnnamedOpetope.Shift(xishapeproof), {
            UnnamedOpetope.address([], Q.shape.dimension - 1):
            Q.source(addr)
        }))
    res = UnnamedOpetopicSet.shift(res, P.source(addr), factorizationName)

    # Derive A
    omega = UnnamedOpetope.Graft(UnnamedOpetope.Shift(P.shapeProof),
                                 UnnamedOpetope.Shift(xishapeproof),
                                 addr.shift())
    res = UnnamedOpetopicSet.graft(
        res,
        UnnamedOpetopicSet.pastingDiagram(
            omega, {
                UnnamedOpetope.address([], P.shape.dimension): suCellName,
                addr.shift(): factorizationName
            }))
    res = UnnamedOpetopicSet.shift(res, cellName, fillerName)

    # Mark A as source universal at xi and target universal
    rawFillerType = res.context[fillerName].type
    fillerType = Type(rawFillerType.source, rawFillerType.target)
    fillerType.targetUniversal = True
    fillerType.sourceUniversal.add(addr.shift())
    res.context[fillerName].type = fillerType

    # Done
    return res
def tuniv(seq: UnnamedOpetopicSet.Sequent, tuCell: str, cell: str,
          factorizationName: str,
          fillerName: str) -> UnnamedOpetopicSet.Sequent:
    """
    From a target universal cell :math:`\\alpha : \\mathbf{P} \\longrightarrow
    t` (whose name is ``tuCell``), and another cell :math:`\\beta : \\mathbf{P}
    \\longrightarrow u`, creates the universal factorization.
    """
    # Inits
    typealpha = seq.context[tuCell].type
    typebeta = seq.context[cell].type
    P = typealpha.source
    targetalpha = typealpha.target
    targetbeta = typebeta.target

    # Checks
    if seq.pastingDiagram is not None:
        raise DerivationError("Apply target univ. prop.",
                              "Sequent cannot type a pasting diagram")
    elif not isTargetUniversal(typealpha):
        raise DerivationError("Apply target univ. prop.",
                              "First cell is expected to be target universal")
    elif typebeta.source != P:
        raise DerivationError(
            "Apply target univ. prop.",
            "Cells are expected to have the same source pasting diagram")
    elif targetalpha is None or targetbeta is None:
        raise RuntimeError(
            "[Apply target univ. prop.] Target universal cell is a point. In "
            "valid derivations, this should not happen")

    # Derive the factorization cell
    n = targetalpha.shape.dimension
    res = UnnamedOpetopicSet.graft(
        deepcopy(seq),
        UnnamedOpetopicSet.pastingDiagram(
            UnnamedOpetope.Shift(targetalpha.shapeProof),
            {UnnamedOpetope.address([], n): targetalpha.name}))
    res = UnnamedOpetopicSet.shift(res, targetbeta.name, factorizationName)

    # Derive the filler
    res = UnnamedOpetopicSet.graft(
        res,
        UnnamedOpetopicSet.pastingDiagram(
            UnnamedOpetope.Graft(
                UnnamedOpetope.Shift(
                    UnnamedOpetope.Shift(targetalpha.shapeProof)),
                P.shapeProof, UnnamedOpetope.address([[]], n + 1)), {
                    UnnamedOpetope.address([], n + 1): factorizationName,
                    UnnamedOpetope.address([[]], n + 1): tuCell
                }))
    res = UnnamedOpetopicSet.shift(res, cell, fillerName)

    # Mark the filler as target universal and source universal at the facto.
    rawFillerType = res.context[fillerName].type
    fillerType = Type(rawFillerType.source, rawFillerType.target)
    fillerType.targetUniversal = True
    fillerType.sourceUniversal.add(UnnamedOpetope.address([], n + 1))
    res.context[fillerName].type = fillerType

    # Done
    return res