def setUp(self): self.t = UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.Address.epsilon(1): "a", UnnamedOpetope.Address.epsilon(0).shift(): "b" }), UnnamedOpetopicSet.Variable("t", UnnamedOpetope.Arrow()))
def setUp(self): self.p = UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("p", UnnamedOpetope.Point()), UnnamedOpetopicSet.Type(UnnamedOpetopicSet.PastingDiagram.point(), None)) self.a = UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("a", UnnamedOpetope.OpetopicInteger(0)), UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.degeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(0), "p"), UnnamedOpetopicSet.Variable("p", UnnamedOpetope.Arrow()))) self.b = UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("b", UnnamedOpetope.OpetopicInteger(0)), UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.degeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(0), "p"), UnnamedOpetopicSet.Variable("p", UnnamedOpetope.Arrow()))) self.c = UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("c", UnnamedOpetope.OpetopicInteger(2)), UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.Address.epsilon(1): "x", UnnamedOpetope.Address.epsilon(0).shift(): "y" }), UnnamedOpetopicSet.Variable("z", UnnamedOpetope.Arrow()))) self.ctx = UnnamedOpetopicSet.Context() + self.p + self.a + self.c
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___init__(self): with self.assertRaises(DerivationError): UnnamedOpetope.Preopetope(-2) UnnamedOpetope.Preopetope(-1) x = UnnamedOpetope.Preopetope(8) self.assertEqual(x.dimension, 8) self.assertFalse(x.isDegenerate) self.assertEqual(x.nodes, {})
def test_shape(self): self.assertEqual(self.a.shape, UnnamedOpetope.Arrow().eval().source) self.assertEqual(self.b.shape, UnnamedOpetope.Arrow().eval().source) self.assertEqual(self.i1.shape, UnnamedOpetope.OpetopicInteger(1).eval().source) self.assertEqual(self.i2.shape, UnnamedOpetope.OpetopicInteger(2).eval().source) self.assertEqual(self.i3.shape, UnnamedOpetope.OpetopicInteger(3).eval().source)
def test___init__(self): UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("x", UnnamedOpetope.OpetopicInteger(2)), self.t) with self.assertRaises(DerivationError): UnnamedOpetopicSet.Typing( UnnamedOpetopicSet.Variable("x", UnnamedOpetope.OpetopicInteger(3)), self.t)
def test___init__(self): UnnamedOpetopicSet.Type( self.s, UnnamedOpetopicSet.Variable("t", UnnamedOpetope.Arrow())) with self.assertRaises(DerivationError): UnnamedOpetopicSet.Type( self.s, UnnamedOpetopicSet.Variable("t", UnnamedOpetope.Point())) UnnamedOpetopicSet.Type(UnnamedOpetopicSet.PastingDiagram.point(), None) with self.assertRaises(DerivationError): UnnamedOpetopicSet.Type(self.s, None)
def test___sub__(self): with self.assertRaises(DerivationError): self.b - UnnamedOpetope.Address.epsilon(1) with self.assertRaises(DerivationError): self.f - UnnamedOpetope.Address.epsilon(2) self.assertEqual(self.c - UnnamedOpetope.Address.epsilon(1), self.b) self.assertEqual(self.d - UnnamedOpetope.Address.fromList(['*'], 1), self.b) self.assertEqual(self.e - UnnamedOpetope.Address.epsilon(2), UnnamedOpetope.Context(3)) self.assertEqual(self.f - UnnamedOpetope.Address.epsilon(1).shift(), UnnamedOpetope.Context(3))
def test___getitem__(self): d = UnnamedOpetopicSet.PastingDiagram.degeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(0), "d") p = UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.Address.epsilon(1): "a", UnnamedOpetope.Address.epsilon(0).shift(): "b" }) with self.assertRaises(DerivationError): d[UnnamedOpetope.Address.epsilon(0)] self.assertEqual(p[UnnamedOpetope.Address.epsilon(1)], "a") self.assertEqual(p[UnnamedOpetope.Address.epsilon(0).shift()], "b")
def test_degen(self): s = UnnamedOpetope.degen(UnnamedOpetope.point()) self.assertEqual( s.context, UnnamedOpetope.Context(2) + (UnnamedOpetope.Address.epsilon(1), UnnamedOpetope.Address.epsilon(0))) self.assertEqual( s.source, UnnamedOpetope.Preopetope.degenerate( UnnamedOpetope.Preopetope.point())) self.assertEqual(s.target, UnnamedOpetope.shift(UnnamedOpetope.point()).source)
def test_nonDegeneratePastingDiagram(self): UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.Address.epsilon(1): "a", UnnamedOpetope.Address.epsilon(0).shift(): "b" }) with self.assertRaises(DerivationError): UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(0), {}) with self.assertRaises(DerivationError): UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.OpetopicInteger(2), {UnnamedOpetope.Address.epsilon(1): "a"})
def setUp(self): self.type_point = UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.point(), None) self.a = UnnamedOpetopicSet.Variable("a", UnnamedOpetope.Point()) self.b = UnnamedOpetopicSet.Variable("b", UnnamedOpetope.Point()) self.c = UnnamedOpetopicSet.Variable("c", UnnamedOpetope.Point()) self.d = UnnamedOpetopicSet.Variable("d", UnnamedOpetope.Point()) self.ab = UnnamedOpetopicSet.Variable("ab", UnnamedOpetope.Arrow()) self.ac = UnnamedOpetopicSet.Variable("ac", UnnamedOpetope.Arrow()) self.bc = UnnamedOpetopicSet.Variable("bc", UnnamedOpetope.Arrow()) self.cd = UnnamedOpetopicSet.Variable("cd", UnnamedOpetope.Arrow()) self.seq = UnnamedOpetopicSet.Sequent() self.seq.context = UnnamedOpetopicSet.Context() + \ UnnamedOpetopicSet.Typing(self.a, self.type_point) + \ UnnamedOpetopicSet.Typing(self.b, self.type_point) + \ UnnamedOpetopicSet.Typing(self.c, self.type_point) + \ UnnamedOpetopicSet.Typing(self.d, self.type_point) + \ UnnamedOpetopicSet.Typing( self.ab, self.type_arrow("a", self.b)) + \ UnnamedOpetopicSet.Typing( self.ac, self.type_arrow("a", self.c)) + \ UnnamedOpetopicSet.Typing( self.bc, self.type_arrow("b", self.c)) + \ UnnamedOpetopicSet.Typing( self.cd, self.type_arrow("c", self.d))
def setUp(self): self.a = UnnamedOpetope.Preopetope(-1) self.b = UnnamedOpetope.Preopetope(0) self.c = UnnamedOpetope.Preopetope.fromDictOfPreopetopes( {UnnamedOpetope.Address.epsilon(0): self.b}) self.d = UnnamedOpetope.Preopetope.degenerate(self.b) self.e = UnnamedOpetope.Preopetope.fromDictOfPreopetopes( {UnnamedOpetope.Address.epsilon(1): self.c}) self.f = UnnamedOpetope.Preopetope.fromDictOfPreopetopes({ UnnamedOpetope.Address.epsilon(1): self.c, UnnamedOpetope.Address.fromList(['*'], 1): self.c })
def point(seq: Sequent, name: Union[str, List[str]]) -> Sequent: """ The :math:`\\textbf{OptSet${}^?$}` :math:`\\texttt{point}` rule. * If argument ``name`` is a ``str``, creates a new point with that name (this is just the :math:`\\texttt{point}`); * if it is a list of ``str``, then creates as many points. """ if isinstance(name, list): res = seq for n in name: res = point(res, n) return res elif isinstance(name, str): if seq.pastingDiagram is not None: raise DerivationError("point rule", "Sequent cannot have a pasting diagram") var = Variable(name, UnnamedOpetope.Point()) if var in seq.context: raise DerivationError( "point rule", "Point shaped variable {name} is already typed in context " "{ctx}", name=name, ctx=str(seq.context)) res = deepcopy(seq) res.context = res.context + Typing(var, Type(PastingDiagram.point(), None)) return res else: raise DerivationError( "point rule", "Argument name is expected to be a str or list of str")
def test_substitution(self): i2 = UnnamedOpetope.Preopetope.fromDictOfPreopetopes({ UnnamedOpetope.Address.epsilon(1): self.c, UnnamedOpetope.Address.fromList(['*'], 1): self.c }) i4 = UnnamedOpetope.Preopetope.fromDictOfPreopetopes({ UnnamedOpetope.Address.epsilon(1): self.c, UnnamedOpetope.Address.fromList(['*'], 1): self.c, UnnamedOpetope.Address.fromList(['*', '*'], 1): self.c, UnnamedOpetope.Address.fromList(['*', '*', '*'], 1): self.c }) i5 = UnnamedOpetope.Preopetope.fromDictOfPreopetopes({ UnnamedOpetope.Address.epsilon(1): self.c, UnnamedOpetope.Address.fromList(['*'], 1): self.c, UnnamedOpetope.Address.fromList(['*', '*'], 1): self.c, UnnamedOpetope.Address.fromList(['*', '*', '*'], 1): self.c, UnnamedOpetope.Address.fromList(['*', '*', '*', '*'], 1): self.c }) ctx = UnnamedOpetope.Context(2) + (UnnamedOpetope.Address.fromList( ['*', '*'], 1), UnnamedOpetope.Address.epsilon(0)) self.assertEqual( UnnamedOpetope.Preopetope.substitution( i4, UnnamedOpetope.Address.fromList(['*', '*'], 1), ctx, i2), i5)
def __str__(self) -> str: srcstr = str() if self.source.degeneracy is None: if self.source.nodes is None: raise RuntimeError("[Pasting diagram, to string] Both the " "degeneracy and node dict of the pasting " "diagram are None. In valid derivations, " "this should not happen") if self.source.shape == UnnamedOpetope.point().source: srcstr = "⧫" else: lines = [] # type: List[str] for addr in self.source.nodes.keys(): if self.isSourceUniversal(addr): lines += [ str(addr) + " ← ∀" + str(self.source.nodes[addr]) ] else: lines += [ str(addr) + " ← " + str(self.source.nodes[addr]) ] srcstr = "{" + ", ".join(lines) + "}" else: srcstr = "{{" + str(self.source.degeneracy) + "}}" if self.isTargetUniversal(): return srcstr + " → ∀" + str(self.target) else: return srcstr + " → " + str(self.target)
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)))
def type_arrow( self, src: str, tgt: UnnamedOpetopicSet.Variable) -> UnnamedOpetopicSet.Type: """ Convenient function to define the type of an arrow shaped cell """ return UnnamedOpetopicSet.Type( UnnamedOpetopicSet.PastingDiagram.nonDegeneratePastingDiagram( UnnamedOpetope.Arrow(), {UnnamedOpetope.Address.epsilon(0): src}), tgt)
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")
def degen(seq: Sequent, name: str) -> Sequent: """ The :math:`\\textbf{OptSet${}^?$}` :math:`\\texttt{degen}` rule. """ if seq.pastingDiagram is not None: raise DerivationError("degen rule", "Sequent cannot have a pasting diagram") res = deepcopy(seq) res.pastingDiagram = PastingDiagram.degeneratePastingDiagram( UnnamedOpetope.Degen(seq.context[name].variable.shapeProof), name) return res
def test_graft(self): i2 = UnnamedOpetope.OpetopicInteger(2).eval() i3 = UnnamedOpetope.OpetopicInteger(3).eval() s = UnnamedOpetope.shift(i3) s = UnnamedOpetope.graft(s, i2, UnnamedOpetope.Address.fromList([['*']], 2)) s = UnnamedOpetope.graft( s, i2, UnnamedOpetope.Address.fromList([['*', '*']], 2)) r = s.context self.assertEqual(r(UnnamedOpetope.Address.fromList([[]], 2)), UnnamedOpetope.Address.fromList([], 1)) self.assertEqual(r(UnnamedOpetope.Address.fromList([['*'], []], 2)), UnnamedOpetope.Address.fromList(['*'], 1)) self.assertEqual(r(UnnamedOpetope.Address.fromList([['*'], ['*']], 2)), UnnamedOpetope.Address.fromList(['*', '*'], 1)) self.assertEqual( r(UnnamedOpetope.Address.fromList([['*', '*'], []], 2)), UnnamedOpetope.Address.fromList(['*', '*', '*'], 1)) self.assertEqual( r(UnnamedOpetope.Address.fromList([['*', '*'], ['*']], 2)), UnnamedOpetope.Address.fromList(['*', '*', '*', '*'], 1))
def __str__(self) -> str: if self.degeneracy is None: if self.nodes is None: raise RuntimeError("[Pasting diagram, to string] Both the " "degeneracy and node dict of the pasting " "diagram are None. In valid derivations, " "this should not happen") if self.shape == UnnamedOpetope.point().source: return "⧫" else: lines = [ str(addr) + " ← " + str(self.nodes[addr]) for addr in self.nodes.keys() ] return "{" + ", ".join(lines) + "}" else: return "{{" + str(self.degeneracy) + "}}"
def toTex(self) -> str: if self.degeneracy is None: if self.nodes is None: raise RuntimeError("[Pasting diagram, to TeX] Both the " "degeneracy and node dict of the pasting " "diagram are None. In valid derivations, " "this should not happen") if self.shape == UnnamedOpetope.point().source: return "\\optZero" else: lines = [ addr.toTex() + " \\sep " + self.nodes[addr] for addr in self.nodes.keys() ] return "\\opetope{" + " \\\\ ".join(lines) + "}" else: return "\\degenopetope{" + self.degeneracy + "}"
def target(self, name: str) -> str: """ Returns the target of the variable whose name is ``name``. """ res = self[name].type.target if self[name].type.source.shape == \ UnnamedOpetope.Point().eval().source: raise DerivationError( "Context, target of variable", "Variable {var} is a point, and do not have a target", var=name) elif res is None: raise RuntimeError( "[Context, target of variable] Variable {var} " "is not a point, but has no target. In valid " "derivations, this should not happen".format(var=name)) return res.name
def __init__(self, source: PastingDiagram, target: Optional[Variable]) -> None: if target is None: if source.shape != UnnamedOpetope.Point().eval().source: raise DerivationError( "Type, creation", "Source pasting diagram is not a point, but target is " "unspecified") elif source.shapeTarget() != target.shape: raise DerivationError( "Type, creation", "Target variable {var} has shape {shape}, should have " "{should}", var=str(target), shape=target.shape, should=source.shapeTarget()) self.source = source self.target = target
def test_shapeTarget(self): self.assertEqual(self.a.shapeTarget(), UnnamedOpetope.Point().eval().source) self.assertEqual(self.b.shapeTarget(), UnnamedOpetope.Point().eval().source) self.assertEqual(self.i1.shapeTarget(), UnnamedOpetope.Arrow().eval().source) self.assertEqual(self.i2.shapeTarget(), UnnamedOpetope.Arrow().eval().source) self.assertEqual(self.i3.shapeTarget(), UnnamedOpetope.Arrow().eval().source) self.assertEqual(self.c.shapeTarget(), UnnamedOpetope.OpetopicInteger(3).eval().source)
def setUp(self): self.a = UnnamedOpetope.Context(0) self.b = UnnamedOpetope.Context(2) self.c = UnnamedOpetope.Context(2) + \ (UnnamedOpetope.Address.epsilon(1), UnnamedOpetope.Address.epsilon(0)) self.d = UnnamedOpetope.Context(2) + \ (UnnamedOpetope.Address.fromList(['*'], 1), UnnamedOpetope.Address.epsilon(0)) self.e = UnnamedOpetope.Context(3) + \ (UnnamedOpetope.Address.epsilon(2), UnnamedOpetope.Address.fromList(['*'], 1)) self.f = UnnamedOpetope.Context(3) + \ (UnnamedOpetope.Address.epsilon(1).shift(), UnnamedOpetope.Address.epsilon(1))
def test_shift(self): s1 = UnnamedOpetope.shift(UnnamedOpetope.point()) s2 = UnnamedOpetope.shift(s1) self.assertEqual( s2.context, UnnamedOpetope.Context(2) + (UnnamedOpetope.Address.epsilon(0).shift(), UnnamedOpetope.Address.epsilon(0))) p = UnnamedOpetope.Preopetope.point() a = UnnamedOpetope.Preopetope(1) a.nodes[UnnamedOpetope.Address.epsilon(0)] = p g = UnnamedOpetope.Preopetope(2) g.nodes[UnnamedOpetope.Address.epsilon(1)] = a self.assertEqual(s1.source, a) self.assertEqual(s1.target, p) self.assertEqual(s2.source, g) self.assertEqual(s2.target, a)
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