def test_graft(self):
     with self.assertRaises(DerivationError):
         UnnamedOpetopicSet.graft(
             UnnamedOpetopicSet.Sequent(),
             UnnamedOpetopicSet.PastingDiagram.degeneratePastingDiagram(
                 UnnamedOpetope.OpetopicInteger(0), "x"))
     with self.assertRaises(DerivationError):
         UnnamedOpetopicSet.graft(
             UnnamedOpetopicSet.Sequent(),
             UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram(
                 UnnamedOpetope.Arrow(),
                 {UnnamedOpetope.Address.epsilon(0): "x"}))
     # Incorrect grafting: ab on top of cd
     with self.assertRaises(DerivationError):
         UnnamedOpetopicSet.graft(
             self.seq,
             UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram(
                 UnnamedOpetope.OpetopicInteger(2), {
                     UnnamedOpetope.Address.epsilon(1): "cd",
                     UnnamedOpetope.Address.epsilon(0).shift(): "ab"
                 }))
     # Correct grafting: ab on top of bc
     UnnamedOpetopicSet.graft(
         self.seq,
         UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram(
             UnnamedOpetope.OpetopicInteger(2), {
                 UnnamedOpetope.Address.epsilon(1): "bc",
                 UnnamedOpetope.Address.epsilon(0).shift(): "ab"
             }))
 def test_shift(self):
     s = UnnamedOpetopicSet.graft(
         self.seq,
         UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram(
             UnnamedOpetope.OpetopicInteger(1),
             {UnnamedOpetope.Address.epsilon(1): "ac"}))
     with self.assertRaises(DerivationError):
         UnnamedOpetopicSet.shift(s, "ab", "A")
     with self.assertRaises(DerivationError):
         UnnamedOpetopicSet.shift(s, "bc", "A")
     UnnamedOpetopicSet.shift(s, "ac", "A")
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
def tfill(seq: UnnamedOpetopicSet.Sequent, targetName: str,
          fillerName: str) -> UnnamedOpetopicSet.Sequent:
    """
    This function takes a :class:`opetopy.UnnamedOpetopicSet.Sequent`, (recall
    that the context of a sequent derivable in :math:`\\textbf{OptSet${}^?$}`
    is a finite opetopic set) typing a pasting diagram :math:`\\mathbf{P}`, and
    solves the Kan filler problem by adding

    * a new cell :math:`t` with name ``targetName``;
    * a new cell :math:`\\alpha : \\mathbf{P} \\longrightarrow t` with name
      ``fillerName``.

    """
    if seq.pastingDiagram is None:
        raise DerivationError(
            "Kan filling, target",
            "Argument sequent expecting to type a pasting diagram")

    # Source of alpha
    P = seq.pastingDiagram
    tPshapeProof = UnnamedOpetope.ProofTree(P.shapeTarget().toDict())

    # Start deriving
    res = deepcopy(seq)
    res.pastingDiagram = None

    # Derive t
    if P.shape.dimension - 1 == 0:
        # t is a point
        res = UnnamedOpetopicSet.point(res, targetName)
    else:
        # Set u, target of t
        if P.shape.isDegenerate:
            u = P.degeneracyVariable()
        else:
            u = seq.context.target(
                P.source(UnnamedOpetope.address([], P.shape.dimension - 1)))
        # Derive Q, source of t
        if P.shapeTarget().isDegenerate:
            Q = UnnamedOpetopicSet.pastingDiagram(tPshapeProof,
                                                  seq.context.target(u))
        else:
            nodes = {}  # type: Dict[UnnamedOpetope.Address, str]
            if P.shape.isDegenerate:
                nodes[UnnamedOpetope.address([], P.shape.dimension - 2)] = \
                    P.degeneracyVariable()
            else:
                readdress = P.shapeProof.eval().context
                for l in P.shape.leafAddresses():
                    p, q = l.edgeDecomposition()
                    nodes[readdress(l)] = seq.context.source(P[p], q)
            Q = UnnamedOpetopicSet.pastingDiagram(tPshapeProof, nodes)
        if Q.shape.isDegenerate:
            res = UnnamedOpetopicSet.degen(res, Q.degeneracyVariable())
        else:
            res = UnnamedOpetopicSet.graft(res, Q)
        # Derive t, target of alpha
        res = UnnamedOpetopicSet.shift(res, u, targetName)

    # Derive P, source of alpha
    if P.shape.isDegenerate:
        res = UnnamedOpetopicSet.degen(res, u)
    else:
        res = UnnamedOpetopicSet.graft(res, P)

    # Derive alpha
    res = UnnamedOpetopicSet.shift(res, targetName, fillerName)

    # Mark t as universal in the type of alpha
    rawFillerType = res.context[fillerName].type
    fillerType = Type(rawFillerType.source, rawFillerType.target)
    fillerType.targetUniversal = True
    res.context[fillerName].type = fillerType

    # Done
    return res