Пример #1
0
    def testPropositionalAGG(self):
        schema = Schema()
        schema.addEntity('A')
        model = Model(schema, [])
        agg = AbstractGroundGraph(model, 'A', 0)
        self.assertAGGEqualNoIntersection(schema, agg, [])

        schema.addAttribute('A', 'A')
        schema.addAttribute('A', 'B')
        schema.addAttribute('A', 'C')
        model = Model(schema, [])
        agg = AbstractGroundGraph(model, 'A', 0)
        self.assertAGGEqualNoIntersection(schema, agg, [])

        schema.addAttribute('A', 'D')
        schema.addAttribute('A', 'E')
        schema.addAttribute('A', 'F')
        schema.addAttribute('A', 'G')
        schema.addAttribute('A', 'H')
        dependencies = [
            '[A].A -> [A].B', '[A].A -> [A].C', '[A].B -> [A].D',
            '[A].C -> [A].D', '[A].E -> [A].F', '[A].E -> [A].G',
            '[A].F -> [A].H', '[A].G -> [A].H'
        ]
        model = Model(schema, dependencies)
        agg = AbstractGroundGraph(model, 'A', 0)
        self.assertAGGEqualNoIntersection(schema, agg, dependencies)
Пример #2
0
    def testGetAncestors(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        model = Model(schema, [])
        agg = AbstractGroundGraph(model, 'A', 0)
        self.assertGetAncestorsEquals(['[A].X'], agg, '[A].X')

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'A')
        schema.addAttribute('A', 'B')
        schema.addAttribute('A', 'C')
        schema.addAttribute('A', 'D')
        schema.addAttribute('A', 'E')
        schema.addAttribute('A', 'F')
        schema.addAttribute('A', 'G')
        schema.addAttribute('A', 'H')
        dependencies = [
            '[A].A -> [A].C', '[A].A -> [A].D', '[A].B -> [A].D',
            '[A].C -> [A].E', '[A].D -> [A].E', '[A].E -> [A].G',
            '[A].E -> [A].H', '[A].F -> [A].H'
        ]
        model = Model(schema, dependencies)
        agg = AbstractGroundGraph(model, 'A', 0)
        self.assertGetAncestorsEquals(
            ['[A].G', '[A].A', '[A].B', '[A].C', '[A].D', '[A].E'], agg,
            '[A].G')
        self.assertGetAncestorsEquals(
            ['[A].F', '[A].A', '[A].B', '[A].C', '[A].D', '[A].E', '[A].H'],
            agg, '[A].H')

        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('C', 'Z')
        schema.addAttribute('AB', 'XY')
        schema.addAttribute('BC', 'YZ')
        model = Model(schema, [
            '[BC, B, AB, A].X -> [BC].YZ', '[AB, B, BC, C].Z -> [AB].XY',
            '[AB, B, AB, A, AB, B].Y -> [AB].XY'
        ])
        agg = AbstractGroundGraph(model, 'A', 6)
        self.assertGetAncestorsEquals([
            '[A, AB].XY', '[A, AB, B, BC, C].Z', '[A, AB, B, AB, A, AB, B].Y',
            ('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y')
        ], agg, '[A, AB].XY')

        self.assertGetAncestorsEquals(
            [('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y')],
            agg, ('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y'))
Пример #3
0
    def testGetSubsumedRelVarInts(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.ONE))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        model = Model(schema, [])
        abAGG = AbstractGroundGraph(model, 'AB', 3)
        self.assertSameSubsumedVariables(['[AB, A].X'], abAGG, '[AB, A].X')
        self.assertSameSubsumedVariables(
            ['[AB, B].Y',
             ('[AB, B].Y', '[AB, A, AB, B].Y')], abAGG, '[AB, B].Y')
        self.assertSameSubsumedVariables(
            ['[AB, A, AB, B].Y',
             ('[AB, B].Y', '[AB, A, AB, B].Y')], abAGG, '[AB, A, AB, B].Y')

        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB1', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addRelationship('AB2', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('AB1', 'XY1')
        schema.addAttribute('AB2', 'XY2')
        model = Model(schema, [])
        aAGG = AbstractGroundGraph(model, 'A', 4)
        self.assertSameSubsumedVariables([
            '[A, AB1, B, AB1, A].X',
            ('[A, AB1, B, AB1, A].X', '[A, AB1, B, AB2, A].X'),
            ('[A, AB1, B, AB1, A].X', '[A, AB2, B, AB1, A].X'),
            ('[A, AB1, B, AB1, A].X', '[A, AB2, B, AB2, A].X')
        ], aAGG, '[A, AB1, B, AB1, A].X')

        # test bad relVar input to getSubsumedVariables
        schema = Schema()
        schema.addEntity('A')
        model = Model(schema, [])
        agg = AbstractGroundGraph(model, 'A', 0)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVar must be a RelationalVariable: found 'None'",
            agg.getSubsumedVariables, None)

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        model = Model(schema, [])
        agg = AbstractGroundGraph(model, 'A', 0)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVar '[A].X2' is not a node in the abstract ground graph",
            agg.getSubsumedVariables, RelationalVariable(['A'], 'X2'))
Пример #4
0
    def dSeparated(self, hopThreshold, relVar1Strs, relVar2Strs, condRelVarStrs,
                   relationalVariableSetChecker=RelationalValidity.checkValidityOfRelationalVariableSet):
        """
        relVar1Strs, relVar2Strs, and condRelVarStrs are sequences of parseable RelationalVariable strings
        Method checks if, in model, are relVars1 and relVars2 d-separated? Constructs the abstract ground graph (AGG) for
        the model, and checks to see if all paths are d-separated.
        """
        if not isinstance(relVar1Strs, collections.Iterable) or not relVar1Strs:
            raise Exception("relVars1 must be a non-empty sequence of parseable RelationalVariable strings")
        relVars1 = {ParserUtil.parseRelVar(relVarStr) for relVarStr in relVar1Strs}

        if not isinstance(relVar2Strs, collections.Iterable) or not relVar2Strs:
            raise Exception("relVars2 must be a non-empty sequence of parseable RelationalVariable strings")
        relVars2 = {ParserUtil.parseRelVar(relVarStr) for relVarStr in relVar2Strs}

        if not isinstance(condRelVarStrs, collections.Iterable):
            raise Exception("condRelVars must be a sequence of parseable RelationalVariable strings")
        condRelVars = {ParserUtil.parseRelVar(condRelVar) for condRelVar in condRelVarStrs}

        # check consistency of all three relational variable sets (perspectives, hop threshold, against schema)
        relationalVariableSetChecker(self.model.schema, hopThreshold, relVars1 | relVars2 | condRelVars)

        perspective = list(relVars1)[0].getBaseItemName()
        if (perspective, hopThreshold) not in self.perspectiveHopThresholdToAgg:
            agg = AbstractGroundGraph(self.model, perspective, hopThreshold)
            ug = agg2ug(agg)
            self.perspectiveHopThresholdToAgg[(perspective, hopThreshold)] = agg
            self.ugs[(perspective, hopThreshold)] = ug
        else:
            agg = self.perspectiveHopThresholdToAgg[(perspective, hopThreshold)]
            ug = self.ugs[(perspective, hopThreshold)]

        # expand relVars1, relVars2, condRelVars with all intersection variables they subsume
        relVars1 = {relVar for relVar1 in relVars1 for relVar in agg.getSubsumedVariables(relVar1)}
        relVars2 = {relVar for relVar2 in relVars2 for relVar in agg.getSubsumedVariables(relVar2)}
        condRelVars = {relVar for condRelVar in condRelVars for relVar in agg.getSubsumedVariables(condRelVar)}

        relVars1 -= condRelVars
        relVars2 -= condRelVars

        if relVars1 & relVars2 != set():
            return False

        if not relVars1 or not relVars2:
            return True

        return bfsReachability(relVars1, relVars2, condRelVars, agg, ug)
Пример #5
0
 def testLongRangeDependencyIsIgnored(self):
     # Build AGG with model with a dependency that is longer than hop threshold
     # the long-range dependence is not (B,h)-reachable for the AGG from perspective B
     schema = Schema()
     schema.addEntity('A')
     schema.addEntity('B')
     schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.ONE))
     schema.addAttribute('B', 'Y1')
     schema.addAttribute('B', 'Y2')
     model = Model(schema, ['[B, AB, A, AB, B].Y1 -> [B].Y2'])
     self.assertAGGEqualNoIntersection(schema,
                                       AbstractGroundGraph(model, 'B', 2),
                                       [])
Пример #6
0
    def testRemoveEdgesForDependency(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'A')
        schema.addAttribute('A', 'B')
        schema.addAttribute('A', 'C')
        schema.addAttribute('A', 'D')
        schema.addAttribute('A', 'E')
        schema.addAttribute('A', 'F')
        schema.addAttribute('A', 'G')
        schema.addAttribute('A', 'H')
        dependencies = [
            '[A].A -> [A].B', '[A].A -> [A].C', '[A].B -> [A].D',
            '[A].C -> [A].D', '[A].E -> [A].F', '[A].E -> [A].G',
            '[A].F -> [A].H', '[A].G -> [A].H'
        ]
        model = Model(schema, dependencies)
        agg = AbstractGroundGraph(model, 'A', 0)
        agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].B -> [A].A'))
        self.assertEqual(8, len(agg.edges()))
        agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].A -> [A].B'))
        self.assertEqual(7, len(agg.edges()))
        self.assertNotIn(
            (ParserUtil.parseRelVar('[A].A'), ParserUtil.parseRelVar('[A].B')),
            agg.edges())
        agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].F -> [A].H'))
        self.assertEqual(6, len(agg.edges()))
        self.assertNotIn(
            (ParserUtil.parseRelVar('[A].F'), ParserUtil.parseRelVar('[A].H')),
            agg.edges())

        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('C', 'Z')
        schema.addAttribute('AB', 'XY')
        schema.addAttribute('BC', 'YZ')
        model = Model(schema, [
            '[BC, B, AB, A].X -> [BC].YZ', '[AB, B, BC, C].Z -> [AB].XY',
            '[AB, B, AB, A, AB, B].Y -> [AB].XY'
        ])
        aAGG = AbstractGroundGraph(model, 'A', 6)
        self.assertEqual(9, len(aAGG.edges()))
        aAGG.removeEdgesForDependency(
            ParserUtil.parseRelDep('[BC, B, AB, A].X -> [BC].YZ'))
        self.assertEqual(7, len(aAGG.edges()))
        aAGG.removeEdgesForDependency(
            ParserUtil.parseRelDep('[AB, B, AB, A, AB, B].Y -> [AB].XY'))
        self.assertEqual(2, len(aAGG.edges()))
Пример #7
0
    def testOneToOneTwoEntityAGG(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 0),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 0),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 0),
                                          [])

        schema.addAttribute('A', 'X')
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 0),
                                          [])
        self.assertAGGEqualNoIntersection(
            schema, AbstractGroundGraph(model, 'B', 1),
            [])  # insufficient hop threshold to give it nodes
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 1),
                                          [])

        schema.addAttribute('B', 'Y')
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 1),
                                          [])

        schema.addAttribute('AB', 'XY')
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 1),
                                          [])

        model = Model(schema, ['[B, AB, A].X -> [B].Y'])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 2),
                                          ['[A].X -> [A, AB, B].Y'])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 2),
                                          ['[B, AB, A].X -> [B].Y'])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 1),
                                          ['[AB, A].X -> [AB, B].Y'])
Пример #8
0
    def testThreeEntityTwoRelationshipsAGG(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('C', 'Z')
        schema.addAttribute('AB', 'XY')
        schema.addAttribute('BC', 'YZ')
        model = Model(schema, [])
        aAGG = AbstractGroundGraph(model, 'A', 6)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[A].X', '[A, AB].XY', '[A, AB, B].Y', '[A, AB, B, AB].XY',
                '[A, AB, B, BC].YZ', '[A, AB, B, AB, A].X',
                '[A, AB, B, BC, C].Z', '[A, AB, B, AB, A, AB].XY',
                '[A, AB, B, BC, C, BC].YZ', '[A, AB, B, AB, A, AB, B].Y',
                '[A, AB, B, BC, C, BC, B].Y'
            ]
        ]
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          aAGG.getRelationalVariableNodes())
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y')
        ])
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            aAGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], aAGG)

        bcAGG = AbstractGroundGraph(model, 'BC', 4)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[BC].YZ', '[BC, B].Y', '[BC, C].Z', '[BC, B, AB].XY',
                '[BC, C, BC].YZ', '[BC, B, AB, A].X', '[BC, C, BC, B].Y',
                '[BC, B, AB, A, AB].XY', '[BC, C, BC, B, AB].XY'
            ]
        ]
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          bcAGG.getRelationalVariableNodes())
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[BC, B].Y', '[BC, C, BC, B].Y'),
            ('[BC, B, AB].XY', '[BC, C, BC, B, AB].XY'),
            ('[BC, B, AB, A, AB].XY', '[BC, C, BC, B, AB].XY')
        ])
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            bcAGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], bcAGG)

        model = Model(schema, [
            '[BC, B, AB, A].X -> [BC].YZ', '[AB, B, BC, C].Z -> [AB].XY',
            '[AB, B, AB, A, AB, B].Y -> [AB].XY'
        ])
        aAGG = AbstractGroundGraph(model, 'A', 6)
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[A].X', '[A, AB, B, BC].YZ'),
            ('[A, AB, B, AB, A].X', '[A, AB, B, BC].YZ'),
            ('[A, AB, B, BC, C].Z', '[A, AB].XY'),
            ('[A, AB, B, BC, C].Z', '[A, AB, B, AB].XY'),
            ('[A, AB, B, AB, A, AB, B].Y', '[A, AB].XY'),
            ('[A, AB, B].Y', '[A, AB, B, AB].XY'),
            ('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, AB].XY'),
            (('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y'),
             '[A, AB].XY'),
            (('[A, AB, B, AB, A, AB, B].Y', '[A, AB, B, BC, C, BC, B].Y'),
             '[A, AB, B, AB].XY')
        ])
        self.assertAGGEdgesEqual(expectedEdges, aAGG)
Пример #9
0
    def testManyToManyTwoEntityTwoRelationshipsAGGNodes(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB1', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addRelationship('AB2', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('AB1', 'XY1')
        schema.addAttribute('AB2', 'XY2')
        model = Model(schema, [])
        aAGG = AbstractGroundGraph(model, 'A', 4)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[A].X', '[A, AB1].XY1', '[A, AB2].XY2', '[A, AB1, B].Y',
                '[A, AB2, B].Y', '[A, AB1, B, AB1].XY1',
                '[A, AB1, B, AB2].XY2', '[A, AB2, B, AB1].XY1',
                '[A, AB2, B, AB2].XY2', '[A, AB1, B, AB1, A].X',
                '[A, AB1, B, AB2, A].X', '[A, AB2, B, AB1, A].X',
                '[A, AB2, B, AB2, A].X'
            ]
        ]
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[A, AB1].XY1', '[A, AB2, B, AB1].XY1'),
            ('[A, AB2].XY2', '[A, AB1, B, AB2].XY2'),
            ('[A, AB1, B].Y', '[A, AB2, B].Y'),
            ('[A, AB1, B, AB1].XY1', '[A, AB2, B, AB1].XY1'),
            ('[A, AB2, B, AB2].XY2', '[A, AB1, B, AB2].XY2'),
            ('[A, AB1, B, AB1, A].X', '[A, AB1, B, AB2, A].X'),
            ('[A, AB1, B, AB1, A].X', '[A, AB2, B, AB1, A].X'),
            ('[A, AB1, B, AB1, A].X', '[A, AB2, B, AB2, A].X'),
            ('[A, AB2, B, AB2, A].X', '[A, AB1, B, AB2, A].X'),
            ('[A, AB2, B, AB2, A].X', '[A, AB2, B, AB1, A].X'),
            ('[A, AB1, B, AB2, A].X', '[A, AB2, B, AB1, A].X')
        ])
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          aAGG.getRelationalVariableNodes())
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            aAGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], aAGG)

        ab1AGG = AbstractGroundGraph(model, 'AB1', 4)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[AB1].XY1', '[AB1, A].X', '[AB1, B].Y', '[AB1, A, AB1].XY1',
                '[AB1, A, AB2].XY2', '[AB1, B, AB1].XY1', '[AB1, B, AB2].XY2',
                '[AB1, A, AB1, B].Y', '[AB1, A, AB2, B].Y',
                '[AB1, B, AB1, A].X', '[AB1, B, AB2, A].X',
                '[AB1, A, AB1, B, AB1].XY1', '[AB1, A, AB2, B, AB1].XY1',
                '[AB1, B, AB1, A, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1',
                '[AB1, A, AB1, B, AB2].XY2', '[AB1, A, AB2, B, AB2].XY2',
                '[AB1, B, AB1, A, AB2].XY2', '[AB1, B, AB2, A, AB2].XY2'
            ]
        ]
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          ab1AGG.getRelationalVariableNodes())
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[AB1, A].X', '[AB1, B, AB1, A].X'),
            ('[AB1, A].X', '[AB1, B, AB2, A].X'),
            ('[AB1, B].Y', '[AB1, A, AB1, B].Y'),
            ('[AB1, B].Y', '[AB1, A, AB2, B].Y'),
            ('[AB1, A, AB1].XY1', '[AB1, B, AB1].XY1'),
            ('[AB1, A, AB1].XY1', '[AB1, A, AB2, B, AB1].XY1'),
            ('[AB1, A, AB1].XY1', '[AB1, B, AB1, A, AB1].XY1'),
            ('[AB1, A, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1'),
            ('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2'),
            ('[AB1, A, AB2].XY2', '[AB1, B, AB2, A, AB2].XY2'),
            ('[AB1, A, AB2].XY2', '[AB1, B, AB1, A, AB2].XY2'),
            ('[AB1, A, AB2].XY2', '[AB1, A, AB1, B, AB2].XY2'),
            ('[AB1, B, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1'),
            ('[AB1, B, AB1].XY1', '[AB1, A, AB1, B, AB1].XY1'),
            ('[AB1, B, AB1].XY1', '[AB1, A, AB2, B, AB1].XY1'),
            ('[AB1, B, AB2].XY2', '[AB1, A, AB2, B, AB2].XY2'),
            ('[AB1, B, AB2].XY2', '[AB1, A, AB1, B, AB2].XY2'),
            ('[AB1, B, AB2].XY2', '[AB1, B, AB1, A, AB2].XY2'),
            ('[AB1, A, AB1, B].Y', '[AB1, A, AB2, B].Y'),
            ('[AB1, B, AB1, A].X', '[AB1, B, AB2, A].X'),
            ('[AB1, A, AB1, B, AB1].XY1', '[AB1, A, AB2, B, AB1].XY1'),
            ('[AB1, A, AB1, B, AB1].XY1', '[AB1, B, AB1, A, AB1].XY1'),
            ('[AB1, A, AB1, B, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1'),
            ('[AB1, A, AB2, B, AB1].XY1', '[AB1, B, AB1, A, AB1].XY1'),
            ('[AB1, A, AB2, B, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1'),
            ('[AB1, B, AB1, A, AB1].XY1', '[AB1, B, AB2, A, AB1].XY1'),
            ('[AB1, A, AB1, B, AB2].XY2', '[AB1, A, AB2, B, AB2].XY2'),
            ('[AB1, A, AB1, B, AB2].XY2', '[AB1, B, AB1, A, AB2].XY2'),
            ('[AB1, A, AB1, B, AB2].XY2', '[AB1, B, AB2, A, AB2].XY2'),
            ('[AB1, A, AB2, B, AB2].XY2', '[AB1, B, AB1, A, AB2].XY2'),
            ('[AB1, A, AB2, B, AB2].XY2', '[AB1, B, AB2, A, AB2].XY2'),
            ('[AB1, B, AB1, A, AB2].XY2', '[AB1, B, AB2, A, AB2].XY2')
        ])
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            ab1AGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], aAGG)

        # test multiple relationships with two dependencies
        model = Model(schema, [
            '[AB2, B, AB1, A].X -> [AB2].XY2', '[AB1, B, AB2].XY2 -> [AB1].XY1'
        ])
        ab1AGG = AbstractGroundGraph(model, 'AB1', 3)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[AB1].XY1', '[AB1, A].X', '[AB1, B].Y', '[AB1, A, AB1].XY1',
                '[AB1, A, AB2].XY2', '[AB1, B, AB1].XY1', '[AB1, B, AB2].XY2',
                '[AB1, A, AB1, B].Y', '[AB1, A, AB2, B].Y',
                '[AB1, B, AB1, A].X', '[AB1, B, AB2, A].X'
            ]
        ]
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          ab1AGG.getRelationalVariableNodes())
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[AB1, A].X', '[AB1, B, AB1, A].X'),
            ('[AB1, A].X', '[AB1, B, AB2, A].X'),
            ('[AB1, B].Y', '[AB1, A, AB1, B].Y'),
            ('[AB1, B].Y', '[AB1, A, AB2, B].Y'),
            ('[AB1, A, AB1].XY1', '[AB1, B, AB1].XY1'),
            ('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2'),
            ('[AB1, A, AB1, B].Y', '[AB1, A, AB2, B].Y'),
            ('[AB1, B, AB1, A].X', '[AB1, B, AB2, A].X')
        ])
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            ab1AGG.getRelationalVariableIntersectionNodes())
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[AB1, B, AB2].XY2', '[AB1].XY1'),
            ('[AB1, B, AB2].XY2', '[AB1, B, AB1].XY1'),
            ('[AB1, A].X', '[AB1, B, AB2].XY2'),
            ('[AB1, B, AB1, A].X', '[AB1, B, AB2].XY2'),
            (('[AB1, A].X', '[AB1, B, AB1, A].X'), '[AB1, B, AB2].XY2'),
            (('[AB1, A].X', '[AB1, B, AB2, A].X'), '[AB1, B, AB2].XY2'),
            ('[AB1, B, AB2].XY2', ('[AB1, A, AB1].XY1', '[AB1, B, AB1].XY1')),
            ('[AB1, A].X', ('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2')),
            ('[AB1, B, AB1, A].X', ('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2')),
            (('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2'), '[AB1].XY1'),
            (('[AB1, A, AB2].XY2', '[AB1, B, AB2].XY2'), '[AB1, B, AB1].XY1'),
            (('[AB1, B, AB1, A].X', '[AB1, B, AB2, A].X'), '[AB1, B, AB2].XY2')
        ])
        self.assertAGGEdgesEqual(expectedEdges, ab1AGG)
Пример #10
0
    def testOneToManyTwoEntityAGG(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.ONE))
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 0),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 0),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 0),
                                          [])

        schema.addAttribute('A', 'X')
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 2),
                                          [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'AB', 2),
                                          [])

        schema.addAttribute('B', 'Y')
        model = Model(schema, [])
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'A', 2),
                                          [])  # putting in max hop threshold
        self.assertAGGEqualNoIntersection(schema,
                                          AbstractGroundGraph(model, 'B', 4),
                                          [])
        abAGG = AbstractGroundGraph(model, 'AB', 3)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr)
            for relVarStr in ['[AB, A].X', '[AB, B].Y', '[AB, A, AB, B].Y']
        ]
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[AB, B].Y', '[AB, A, AB, B].Y')
        ])
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          abAGG.getRelationalVariableNodes())
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            abAGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], abAGG)
        # test that order of relVar1, relVar2 for RelationalVariableIntersection doesn't matter
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[AB, A, AB, B].Y', '[AB, B].Y')
        ])
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            abAGG.getRelationalVariableIntersectionNodes())

        model = Model(schema, ['[A, AB, B].Y -> [A].X'])
        aAGG = AbstractGroundGraph(model, 'A', 2)
        expectedEdges = self.relVarStrPairsToRelVarPairs([('[A, AB, B].Y',
                                                           '[A].X')])
        self.assertAGGEdgesEqual(expectedEdges, aAGG)

        # test that extended dependencies are only added among nodes that exist in the AGG (have an appropriate number of hops)
        bAGG = AbstractGroundGraph(model, 'B', 2)
        expectedEdges = self.relVarStrPairsToRelVarPairs([('[B].Y',
                                                           '[B, AB, A].X')])
        self.assertAGGEdgesEqual(expectedEdges, bAGG)

        bAGG = AbstractGroundGraph(model, 'B', 4)
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[B].Y', '[B, AB, A].X'), ('[B, AB, A, AB, B].Y', '[B, AB, A].X')
        ])
        self.assertAGGEdgesEqual(expectedEdges, bAGG)

        # test dependencies get inherited for intersection nodes
        abAGG = AbstractGroundGraph(model, 'AB', 3)
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[AB, B].Y', '[AB, A].X'), ('[AB, A, AB, B].Y', '[AB, A].X'),
            (('[AB, A, AB, B].Y', '[AB, B].Y'), '[AB, A].X')
        ])
        self.assertAGGEdgesEqual(expectedEdges, abAGG)

        schema.addAttribute('B', 'Z')
        model = Model(schema, [])
        abAGG = AbstractGroundGraph(model, 'AB', 3)
        expectedRelVarNodes = [
            ParserUtil.parseRelVar(relVarStr) for relVarStr in [
                '[AB, A].X', '[AB, B].Y', '[AB, A, AB, B].Y', '[AB, B].Z',
                '[AB, A, AB, B].Z'
            ]
        ]
        expectedRelVarIntNodes = self.relVarStrPairsToRelVarInts([
            ('[AB, B].Y', '[AB, A, AB, B].Y'),
            ('[AB, B].Z', '[AB, A, AB, B].Z')
        ])
        TestUtil.assertUnorderedListEqual(self, expectedRelVarNodes,
                                          abAGG.getRelationalVariableNodes())
        TestUtil.assertUnorderedListEqual(
            self, expectedRelVarIntNodes,
            abAGG.getRelationalVariableIntersectionNodes())
        self.assertAGGEdgesEqual([], abAGG)

        model = Model(schema, [
            '[A, AB, B].Y -> [A].X', '[A, AB, B].Z -> [A].X', '[B].Y -> [B].Z'
        ])
        aAGG = AbstractGroundGraph(model, 'A', 2)
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[A, AB, B].Y', '[A].X'), ('[A, AB, B].Z', '[A].X'),
            ('[A, AB, B].Y', '[A, AB, B].Z')
        ])
        self.assertAGGEdgesEqual(expectedEdges, aAGG)

        abAGG = AbstractGroundGraph(model, 'AB', 3)
        expectedEdges = self.relVarStrPairsToRelVarPairs([
            ('[AB, A, AB, B].Y', '[AB, A, AB, B].Z'),
            ('[AB, A, AB, B].Y', '[AB, A].X'), ('[AB, B].Y', '[AB, B].Z'),
            ('[AB, A, AB, B].Z', '[AB, A].X'), ('[AB, B].Y', '[AB, A].X'),
            ('[AB, B].Z', '[AB, A].X'),
            (('[AB, B].Y', '[AB, A, AB, B].Y'), '[AB, A].X'),
            (('[AB, B].Y', '[AB, A, AB, B].Y'), '[AB, B].Z'),
            (('[AB, B].Y', '[AB, A, AB, B].Y'), '[AB, A, AB, B].Z'),
            (('[AB, B].Z', '[AB, A, AB, B].Z'), '[AB, A].X'),
            ('[AB, A, AB, B].Y', ('[AB, B].Z', '[AB, A, AB, B].Z')),
            ('[AB, B].Y', ('[AB, B].Z', '[AB, A, AB, B].Z'))
        ])
        self.assertAGGEdgesEqual(expectedEdges, abAGG)
Пример #11
0
 def constructAggsFromDependencies(self, dependencies, times=2):
     schemaDepWrapper = SchemaDependencyWrapper(self.schema, dependencies)
     perspectives = [si.name for si in self.schema.getSchemaItems()]
     self.perspectiveToAgg = {perspective: AbstractGroundGraph(schemaDepWrapper, perspective, times*self.hopThreshold)
                                   for perspective in perspectives}
Пример #12
0
print('Oriented recall:',
      ModelEvaluation.orientedRecall(model, rcdl.orientedDependencies))

assert ModelEvaluation.orientedRecall(model, rcdl.orientedDependencies) == \
       ModelEvaluation.orientedRecall(model, rcd.orientedDependencies) == \
       0.0

# Demonstrate that there is no 'unshielded triple' in AGGs for the counter-example.
schema, model = shlee.RCDLight.incompleteness_example()
hopThreshold = max(len(d.relVar1.path) + 1 for d in model.dependencies)
oracle = Oracle(model, 3 * hopThreshold)

schemaDepWrapper = SchemaDependencyWrapper(schema, model.dependencies)
perspectives = [si.name for si in schema.getSchemaItems()]
perspectiveToAgg = {
    perspective: AbstractGroundGraph(schemaDepWrapper, perspective,
                                     3 * hopThreshold)
    for perspective in perspectives
}

for agg in perspectiveToAgg.values():
    for node1 in agg.nodes():
        neighbors1 = set(agg.predecessors(node1) + agg.successors(node1))
        for node2 in neighbors1:
            neighbors2 = set(agg.predecessors(node2) +
                             agg.successors(node2)) - {node1}
            for node3 in neighbors2:
                if node3 not in neighbors1:
                    if not isinstance(node1, RelationalVariable) or not isinstance(node2, RelationalVariable) or \
                            not isinstance(node3, RelationalVariable):
                        continue
                    print(node1, node2, node3)