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 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 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 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_point(self): s = UnnamedOpetopicSet.point(UnnamedOpetopicSet.Sequent(), "x") s = UnnamedOpetopicSet.point(s, "y") self.assertEqual(len(s.context), 2) with self.assertRaises(DerivationError): UnnamedOpetopicSet.point(s, "x") s.pastingDiagram = UnnamedOpetopicSet.PastingDiagram.point() with self.assertRaises(DerivationError): UnnamedOpetopicSet.point(s, "z")
def test_degen(self): s = UnnamedOpetopicSet.point(UnnamedOpetopicSet.Sequent(), "x") with self.assertRaises(DerivationError): UnnamedOpetopicSet.degen(s, "y") s = UnnamedOpetopicSet.degen(s, "x") self.assertIsNotNone(s.pastingDiagram.degeneracy) self.assertEqual(s.pastingDiagram.degeneracy, "x") self.assertIsNone(s.pastingDiagram.nodes) with self.assertRaises(DerivationError): UnnamedOpetopicSet.degen(s, "x")
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 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 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 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
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
def test___eq__(self): self.assertEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(0), "a"), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(0), "a")) self.assertNotEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(0), "a"), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(0), "b")) self.assertNotEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(0), "a"), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.Degen(UnnamedOpetope.Arrow()), "a")) self.assertNotEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(1), {UnnamedOpetope.address([], 1): "a"}), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(1), {UnnamedOpetope.address([], 1): "b"})) self.assertNotEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(1), {UnnamedOpetope.address([], 1): "a"}), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.address([], 1): "a", UnnamedOpetope.address(['*']): "a" })) self.assertEqual( UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.address([], 1): "a", UnnamedOpetope.address(['*']): "b" }), UnnamedOpetopicSet.pastingDiagram( UnnamedOpetope.OpetopicInteger(2), { UnnamedOpetope.address(['*']): "b", UnnamedOpetope.address([], 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.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