Beispiel #1
0
    def testDuplicateAttrNames(self):
        schemaWithEntityA = Schema()
        schemaWithEntityA.addEntity('A')
        schemaWithEntityA.addAttribute('A', 'X', Attribute.INTEGER)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema already has attribute named 'X' for item 'A'",
            schemaWithEntityA.addAttribute, 'A', 'X', Attribute.INTEGER)

        schemaWithEntityA.addEntity('B')
        schemaWithEntityA.addRelationship('AB', ('A', Schema.ONE),
                                          ('B', Schema.ONE))
        schemaWithEntityA.addAttribute('AB', 'XY', Attribute.INTEGER)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema already has attribute named 'XY' for item 'AB'",
            schemaWithEntityA.addAttribute, 'AB', 'XY', Attribute.INTEGER)

        a = schemaWithEntityA.getEntity('A')
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema already has attribute named 'X' for item 'A'",
            a.addAttribute, 'X', Attribute.INTEGER)

        ab = schemaWithEntityA.getRelationship('AB')
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema already has attribute named 'XY' for item 'AB'",
            ab.addAttribute, 'XY', Attribute.INTEGER)
Beispiel #2
0
    def testSetUndirectedSkeleton(self):
        schema = Schema()
        model = Model(schema, [])
        pc = PC(schema, Oracle(model))
        undirectedSkeleton = nx.DiGraph()
        pc.setUndirectedSkeleton(undirectedSkeleton)
        self.assertEqual(undirectedSkeleton, pc.undirectedSkeleton)

        TestUtil.assertRaisesMessage(self, Exception, "Undirected skeleton must be a networkx DiGraph: found None",
             pc.setUndirectedSkeleton, None)

        # nodes must match the attributes of the schema
        undirectedSkeleton = nx.DiGraph()
        undirectedSkeleton.add_node(ParserUtil.parseRelVar('[A].X'))
        TestUtil.assertRaisesMessage(self, Exception, "Undirected skeleton's nodes must match schema attributes",
             pc.setUndirectedSkeleton, undirectedSkeleton)

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        model = Model(schema, [])
        pc = PC(schema, Oracle(model))
        undirectedSkeleton = nx.DiGraph()
        TestUtil.assertRaisesMessage(self, Exception, "Undirected skeleton's nodes must match schema attributes",
             pc.setUndirectedSkeleton, undirectedSkeleton)
Beispiel #3
0
    def testBadInput(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        dataStore = InMemoryDataStore()
        linearCITest = LinearCITest(schema, dataStore)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVar1Str must be a parseable RelationalVariable string",
            linearCITest.isConditionallyIndependent, None, '[A].X2', [])
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVar2Str must be a parseable RelationalVariable string",
            linearCITest.isConditionallyIndependent, '[A].X1', None, [])
        TestUtil.assertRaisesMessage(
            self, Exception,
            "condRelVarStrs must be a sequence of parseable RelationalVariable strings",
            linearCITest.isConditionallyIndependent, '[A].X1', '[A].X2', None)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "condRelVarStrs must be a sequence of parseable RelationalVariable strings",
            linearCITest.isConditionallyIndependent, '[A].X1', '[A].X2',
            '[A].X2')

        # relVar2Str MUST be singleton
        schema.addEntity('B')
        schema.addAttribute('B', 'Y', Attribute.FLOAT)
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        TestUtil.assertRaisesMessage(self, Exception,
                                     "relVar2Str must have a singleton path",
                                     linearCITest.isConditionallyIndependent,
                                     '[A].X1', '[A, AB, B].Y', [])
Beispiel #4
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)
    def testOneRelationship(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.MANY))

        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')
        schema.addAttribute('AB', 'XY')

        relDeps = RelationalSpace.getRelationalDependencies(
            schema, 0, includeExistence=True)
        hop0 = []
        self.assertTrue(
            all([
                isinstance(relDep, RelationalDependency) for relDep in relDeps
            ]))
        TestUtil.assertUnorderedListEqual(self, hop0,
                                          [str(relDep) for relDep in relDeps])

        relDeps = RelationalSpace.getRelationalDependencies(
            schema, 1, includeExistence=True)
        hop1 = [
            '[A, AB].XY -> [A].X', '[A, AB].exists -> [A].X',
            '[AB, A].X -> [AB].XY', '[AB, A].X -> [AB].exists',
            '[AB, B].Y -> [AB].XY', '[AB, B].Y -> [AB].exists',
            '[B, AB].XY -> [B].Y', '[B, AB].exists -> [B].Y'
        ]
        self.assertTrue(
            all([
                isinstance(relDep, RelationalDependency) for relDep in relDeps
            ]))
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1,
                                          [str(relDep) for relDep in relDeps])

        relDeps = RelationalSpace.getRelationalDependencies(
            schema, 2, includeExistence=True)
        hop2 = [
            '[A, AB, B].Y -> [A].X', '[AB, B, AB].exists -> [AB].XY',
            '[B, AB, A].X -> [B].Y'
        ]
        self.assertTrue(
            all([
                isinstance(relDep, RelationalDependency) for relDep in relDeps
            ]))
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2,
                                          [str(relDep) for relDep in relDeps])

        relDeps = RelationalSpace.getRelationalDependencies(
            schema, 3, includeExistence=True)
        hop3 = [
            '[A, AB, B, AB].XY -> [A].X', '[A, AB, B, AB].exists -> [A].X',
            '[AB, B, AB, A].X -> [AB].XY'
        ]
        self.assertTrue(
            all([
                isinstance(relDep, RelationalDependency) for relDep in relDeps
            ]))
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2 + hop3,
                                          [str(relDep) for relDep in relDeps])
Beispiel #6
0
    def testBadRelVarInput(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        model = Model(schema, [])
        dsep = DSeparation(model)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVars1 must be a non-empty sequence of parseable RelationalVariable strings",
            dsep.dSeparated, 0, None, ['[A].X2'], [])
        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVars2 must be a non-empty sequence of parseable RelationalVariable strings",
            dsep.dSeparated, 0, ['[A].X1'], None, [])
        TestUtil.assertRaisesMessage(
            self, Exception,
            "condRelVars must be a sequence of parseable RelationalVariable strings",
            dsep.dSeparated, 0, ['[A].X1'], ['[A].X2'], None)

        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVars1 must be a non-empty sequence of parseable RelationalVariable strings",
            dsep.dSeparated, 0, [], ['[A].X2'], [])

        TestUtil.assertRaisesMessage(
            self, Exception,
            "relVars2 must be a non-empty sequence of parseable RelationalVariable strings",
            DSeparation.dSeparated, model, 0, ['[A].X1'], [], [])
Beispiel #7
0
    def testInvalidRelationalDependencies(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')

        # Check that entire dependency is canonical (relVar2 has a singleton path)
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Dependency '[B].Y -> [B, AB, A].X' is not canonical",
            RelationalValidity.checkRelationalDependencyValidity, schema,
            ParserUtil.parseRelDep('[B].Y -> [B, AB, A].X'))

        # Check that base items are the same in both paths
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Dependency '[B].Y -> [A].X' has inconsistent base items",
            RelationalValidity.checkRelationalDependencyValidity, schema,
            ParserUtil.parseRelDep('[B].Y -> [A].X'))

        # enforce that the relational variables are checked for consistency against the schema
        # using RelationalValidity.checkRelationalVariableValidity
        mockRelVarChecker = MagicMock(
            wraps=RelationalValidity.checkRelationalVariableValidity)
        RelationalValidity.checkRelationalDependencyValidity(
            schema,
            ParserUtil.parseRelDep('[A, AB, B].Y -> [A].X'),
            relationalVariableChecker=mockRelVarChecker)
        self.assertEqual(2, mockRelVarChecker.call_count)
Beispiel #8
0
    def testInvalidSetOfRelationalVariables(self):
        # all relvars must have the same perspective
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        schema.addAttribute('A', 'X')
        schema.addAttribute('B', 'Y')

        TestUtil.assertRaisesMessage(
            self, Exception,
            "Perspective is not consistent across all relational variables",
            RelationalValidity.checkValidityOfRelationalVariableSet, schema, 0,
            [
                ParserUtil.parseRelVar(relVarStr)
                for relVarStr in ['[A].X', '[B].Y']
            ])

        TestUtil.assertRaisesMessage(
            self, Exception,
            "Perspective is not consistent across all relational variables",
            RelationalValidity.checkValidityOfRelationalVariableSet, schema, 0,
            [
                ParserUtil.parseRelVar(relVarStr)
                for relVarStr in ['[B].Y', '[A].X']
            ])

        # all relvars must be consistent with hop threshold
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Relational variable '[A, AB, B].Y' is longer than the hop threshold",
            RelationalValidity.checkValidityOfRelationalVariableSet, schema, 0,
            [
                ParserUtil.parseRelVar(relVarStr)
                for relVarStr in ['[A].X', '[A, AB, B].Y']
            ])

        TestUtil.assertRaisesMessage(
            self, Exception,
            "Relational variable '[A, AB, B].Y' is longer than the hop threshold",
            RelationalValidity.checkValidityOfRelationalVariableSet, schema, 1,
            [
                ParserUtil.parseRelVar(relVarStr)
                for relVarStr in ['[A, AB, B].Y', '[A].X']
            ])

        # enforce that the relational variables are checked for consistency against the schema
        # using RelationalValidity.checkRelationalVariableValidity
        mockRelVarChecker = MagicMock(
            wraps=RelationalValidity.checkRelationalVariableValidity)
        RelationalValidity.checkValidityOfRelationalVariableSet(
            schema,
            2, [
                ParserUtil.parseRelVar(relVarStr)
                for relVarStr in ['[A, AB, B].Y', '[A].X']
            ],
            relationalVariableChecker=mockRelVarChecker)
        self.assertEqual(2, mockRelVarChecker.call_count)
Beispiel #9
0
 def testChoseTooFewDependencies(self):
     schema = Schema()
     schema.addEntity('A')
     schema.addAttribute('A', 'X1')
     schema.addAttribute('A', 'X2')
     schema.addAttribute('A', 'X3')
     dependencies = ['[A].X3 -> [A].X1', '[A].X1 -> [A].X2', '[A].X2 -> [A].X3', '[A].X2 -> [A].X1',
                     '[A].X1 -> [A].X3', '[A].X3 -> [A].X2']
     TestUtil.assertRaisesMessage(self, Exception, "Could not generate a model: failed to find a model with 4 dependenc[y|ies]",
                 ModelGenerator.generateModel, schema, 0, 4, dependencies=dependencies,
                 randomPicker=lambda depsList, _: [depsList[0]])
Beispiel #10
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),
                                       [])
Beispiel #11
0
 def testRemoveCommonCondRelVarOnlyFromRelVars(self):
     schema = Schema()
     schema.addEntity('A')
     schema.addAttribute('A', 'X1')
     schema.addAttribute('A', 'X2')
     schema.addAttribute('A', 'X3')
     model = Model(schema, ['[A].X1 -> [A].X2', '[A].X2 -> [A].X3'])
     dsep = DSeparation(model)
     self.assertTrue(
         dsep.dSeparated(0, ['[A].X1', '[A].X2'], ['[A].X3'], ['[A].X2']))
     self.assertTrue(
         dsep.dSeparated(0, ['[A].X1', '[A].X2'], ['[A].X2', '[A].X3'],
                         ['[A].X2']))
Beispiel #12
0
    def testExtendPaths(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addAttribute('AB', 'XY1')
        schema.addAttribute('AB', 'XY2')
        schema.addAttribute('AB', 'XY3')

        from causality.dseparation import AbstractGroundGraph as AGG_module
        self.assertEqual([['AB', 'B', 'AB', 'A', 'AB', 'B', 'AB']],
                         AGG_module.extendPath(schema, ['AB', 'B', 'AB'],
                                               ['AB', 'A', 'AB', 'B', 'AB']))
Beispiel #13
0
    def testOneEntity(self):
        schema = Schema()
        schema.addEntity('A')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[A].exists'], [str(relVar) for relVar in relVars])

        schema.addAttribute('A', 'X1')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[A].exists', '[A].X1'], [str(relVar) for relVar in relVars])

        schema.addAttribute('A', 'X2')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[A].exists', '[A].X1', '[A].X2'], [str(relVar) for relVar in relVars])

        schema = Schema()
        schema.addEntity('B')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[B].exists'], [str(relVar) for relVar in relVars])

        schema.addAttribute('B', 'Y')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[B].exists', '[B].Y'], [str(relVar) for relVar in relVars])

        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        relVars = RelationalSpace.getRelationalVariables(schema, 0, includeExistence=True)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, ['[A].exists', '[A].X', '[B].exists', '[B].Y'],
            [str(relVar) for relVar in relVars])
Beispiel #14
0
    def testIntersectingInputRelVars(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        model = Model(schema, [])
        dsep = DSeparation(model)
        self.assertFalse(dsep.dSeparated(0, ['[A].X1'], ['[A].X1'], []))
        self.assertFalse(
            dsep.dSeparated(0, ['[A].X2', '[A].X1'], ['[A].X1', '[A].X2'], []))
        self.assertFalse(
            dsep.dSeparated(0, ['[A].X2', '[A].X1'], ['[A].X1'], []))

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        schema.addEntity('B')
        schema.addAttribute('B', 'Y')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addEntity('C')
        schema.addAttribute('C', 'Z')
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))
        model = Model(schema, [])
        dsep = DSeparation(model)
        self.assertFalse(
            dsep.dSeparated(6, ['[A, AB, B, AB, A, AB, B].Y'],
                            ['[A, AB, B, BC, C, BC, B].Y'], []))
Beispiel #15
0
    def testTwoVariableModels(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        model = Model(schema, [])
        dsep = DSeparation(model)
        self.assertTrue(dsep.dSeparated(0, ['[A].X1'], ['[A].X2'], []))
        self.assertTrue(dsep.dSeparated(0, ['[A].X2'], ['[A].X1'], []))

        model = Model(schema, ['[A].X1 -> [A].X2'])
        dsep = DSeparation(model)
        self.assertFalse(dsep.dSeparated(0, ['[A].X1'], ['[A].X2'], []))
        self.assertFalse(dsep.dSeparated(0, ['[A].X2'], ['[A].X1'], []))
Beispiel #16
0
 def testPCLearnModel(self):
     schema = Schema()
     schema.addEntity('A')
     schema.addAttribute('A', 'X')
     schema.addAttribute('A', 'Y')
     schema.addAttribute('A', 'Z')
     schema.addAttribute('A', 'W')
     model = Model(schema, ['[A].X -> [A].Y', '[A].X -> [A].W', '[A].X -> [A].Z', '[A].Y -> [A].Z', '[A].W -> [A].Z'])
     pc = PC(schema, Oracle(model))
     pc.learnModel()
     expectedNodes = ['[A].X', '[A].Y', '[A].Z', '[A].W']
     expectedEdges = [('[A].X', '[A].Z'), ('[A].Y', '[A].Z'), ('[A].W', '[A].Z'), ('[A].X', '[A].Y'),
                      ('[A].Y', '[A].X'), ('[A].W', '[A].X'), ('[A].X', '[A].W')]
     self.assertPCOutputEqual(expectedNodes, expectedEdges, None, None, pc.partiallyDirectedGraph, None, None)
Beispiel #17
0
    def testModelFileIO(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.MANY))
        schema.addRelationship('BC', ('B', Schema.MANY), ('C', Schema.MANY))
        schema.addAttribute('A', 'X', Attribute.INTEGER)
        schema.addAttribute('B', 'Y', Attribute.INTEGER)
        schema.addAttribute('C', 'Z', Attribute.INTEGER)
        schema.addAttribute('AB', 'XY1', Attribute.INTEGER)
        schema.addAttribute('AB', 'XY2', Attribute.INTEGER)
        schema.addAttribute('BC', 'YZ', Attribute.INTEGER)

        schema.toFile('schema.json')

        model = Model(schema, [])
        model.toFile('model.json')
        loadedModel = Model.fromFile('schema.json', 'model.json')
        self.assertEqual(model, loadedModel)

        model = Model(schema, ['[A, AB, B].Y -> [A].X'])
        model.toFile('model.json')
        loadedModel = Model.fromFile('schema.json', 'model.json')
        self.assertEqual(model, loadedModel)

        model = Model(
            schema,
            ['[A, AB, B].Y -> [A].X', '[AB, B, BC, C].Z -> [AB].exists'])
        model.toFile('model.json')
        loadedModel = Model.fromFile('schema.json', 'model.json')
        self.assertEqual(model, loadedModel)
Beispiel #18
0
    def testInvalidRelationalVariables(self):
        schema = Schema()
        schema.addEntity('A')
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema item 'A' has no attribute 'X' in relationalVariable '[A].X'",
            RelationalValidity.checkRelationalVariableValidity, schema,
            ParserUtil.parseRelVar('[A].X'))

        schema.addAttribute('A', 'X')
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema item 'A' has no attribute 'Y' in relationalVariable '[A].Y'",
            RelationalValidity.checkRelationalVariableValidity, schema,
            ParserUtil.parseRelVar('[A].Y'))

        self.assertIsNone(
            RelationalValidity.checkRelationalVariableValidity(
                schema, ParserUtil.parseRelVar('[A].exists')))

        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema item 'AB' has no attribute 'XY' in relationalVariable '[A, AB].XY'",
            RelationalValidity.checkRelationalVariableValidity, schema,
            ParserUtil.parseRelVar('[A, AB].XY'))

        self.assertIsNone(
            RelationalValidity.checkRelationalVariableValidity(
                schema, ParserUtil.parseRelVar('[A, AB].exists')))

        TestUtil.assertRaisesMessage(
            self, Exception,
            "Schema item 'B' has no attribute 'Y' in relationalVariable '[A, AB, B].Y'",
            RelationalValidity.checkRelationalVariableValidity, schema,
            ParserUtil.parseRelVar('[A, AB, B].Y'))
        schema.addAttribute('B', 'Y')

        # enforce that the relational paths are checked for consistency against the schema
        # using RelationalValidity.checkRelationalPathValidity
        mockRelPathChecker = MagicMock(
            wraps=RelationalValidity.checkRelationalPathValidity)
        RelationalValidity.checkRelationalVariableValidity(
            schema,
            ParserUtil.parseRelVar('[A, AB, B].Y'),
            relationalPathChecker=mockRelPathChecker)
        self.assertEqual(1, mockRelPathChecker.call_count)
Beispiel #19
0
    def testOracle(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        schema.addAttribute('A', 'X3')
        schema.addAttribute('A', 'X4')
        model = Model(
            schema,
            ['[A].X1 -> [A].X3', '[A].X2 -> [A].X3', '[A].X3 -> [A].X4'])
        oracle = Oracle(model)
        self.assertTrue(isinstance(oracle, CITest))
        self.assertTrue(
            oracle.isConditionallyIndependent('[A].X1', '[A].X2', []))
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X1', '[A].X2', ['[A].X3']))
        self.assertFalse(
            oracle.isConditionallyIndependent(
                '[A].X1', '[A].X2',
                ['[A].X4']))  # tests conditioning on descendant of a collider
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X1', '[A].X2',
                                              ['[A].X3', '[A].X4']))

        # model has multiple paths
        model = Model(schema, [
            '[A].X1 -> [A].X3', '[A].X1 -> [A].X2', '[A].X2 -> [A].X4',
            '[A].X4 -> [A].X3'
        ])
        oracle = Oracle(model)
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X1', '[A].X4', []))
        self.assertTrue(
            oracle.isConditionallyIndependent('[A].X1', '[A].X4', ['[A].X2']))
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X1', '[A].X4',
                                              ['[A].X2', '[A].X3']))
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X2', '[A].X3', []))
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X2', '[A].X3', ['[A].X1']))
        self.assertFalse(
            oracle.isConditionallyIndependent('[A].X2', '[A].X3', ['[A].X4']))
        self.assertTrue(
            oracle.isConditionallyIndependent('[A].X2', '[A].X3',
                                              ['[A].X1', '[A].X4']))
Beispiel #20
0
 def testTwoEntities(self):
     schema = Schema()
     schema.addEntity('A')
     schema.addEntity('B')
     schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.MANY))
     schema.addAttribute('A', 'X')
     schema.addAttribute('B', 'Y')
     schema.addAttribute('AB', 'XY')
     dependencies = ['[A, AB].XY -> [A].X', '[A, AB].exists -> [A].X', '[AB, A].X -> [AB].XY',
                     '[AB, A].X -> [AB].exists', '[AB, B].Y -> [AB].XY', '[AB, B].Y -> [AB].exists',
                     '[B, AB].XY -> [B].Y', '[B, AB].exists -> [B].Y', '[A, AB, B].Y -> [A].X',
                     '[AB, B, AB].exists -> [AB].XY', '[B, AB, A].X -> [B].Y']
     model = ModelGenerator.generateModel(schema, 2, 3, dependencies=dependencies,
         randomPicker=lambda depsList, _: [depsList[0]])
     self.assertIsInstance(model, Model)
     TestUtil.assertUnorderedListEqual(self, ['[A, AB].XY -> [A].X', '[A, AB].exists -> [A].X', '[AB, B].Y -> [AB].XY'],
         [str(dep) for dep in model.dependencies])
Beispiel #21
0
 def testPhaseIBiggerConditionalSets(self):
     schema = Schema()
     schema.addEntity('A')
     schema.addAttribute('A', 'X')
     schema.addAttribute('A', 'Y')
     schema.addAttribute('A', 'Z')
     schema.addAttribute('A', 'W')
     model = Model(schema, ['[A].X -> [A].Y', '[A].X -> [A].Z', '[A].Y -> [A].W', '[A].Z -> [A].W'])
     pc = PC(schema, Oracle(model))
     pc.pcPhaseI()
     expectedNodes = ['[A].X', '[A].Y', '[A].Z', '[A].W']
     expectedEdges = [('[A].X', '[A].Y'), ('[A].Y', '[A].X'), ('[A].X', '[A].Z'), ('[A].Z', '[A].X'),
                      ('[A].W', '[A].Y'), ('[A].Y', '[A].W'), ('[A].W', '[A].Z'), ('[A].Z', '[A].W')]
     expectedSepset = {('[A].X', '[A].W'): {'[A].Y', '[A].Z'}, ('[A].W', '[A].X'): {'[A].Y', '[A].Z'},
                       ('[A].Y', '[A].Z'): {'[A].X'}, ('[A].Z', '[A].Y'): {'[A].X'}}
     self.assertPCOutputEqual(expectedNodes, expectedEdges, expectedSepset, None, pc.undirectedSkeleton,
                              pc.sepsets, None)
Beispiel #22
0
def incompleteness_example():
    schema = Schema()
    schema.addEntity("E1")
    schema.addEntity("E2")
    schema.addEntity("E3")
    schema.addRelationship("R1", ("E1", Schema.ONE), ("E2", Schema.ONE))
    schema.addRelationship("R2", ("E2", Schema.ONE), ("E3", Schema.ONE))
    schema.addRelationship("R3", ("E2", Schema.ONE), ("E3", Schema.ONE))
    schema.addAttribute("R1", "X")
    schema.addAttribute("R2", "Y")
    schema.addAttribute("E2", "Z")

    d1 = RelationalDependency(RelationalVariable(["R2", "E2", "R1"], "X"), RelationalVariable(["R2"], "Y"))
    d2 = RelationalDependency(RelationalVariable(["R2", "E3", "R3", "E2"], "Z"), RelationalVariable(["R2"], "Y"))
    d3 = RelationalDependency(RelationalVariable(["R1", "E2", "R2", "E3", "R3", "E2"], "Z"),
                              RelationalVariable(["R1"], "X"))
    model = Model(schema, [d1, d2, d3])
    return schema, model
Beispiel #23
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'))
Beispiel #24
0
 def testSetPhaseIPattern(self):
     # edges in skeleton and sepsets should be useful for Phase II
     schema = Schema()
     schema.addEntity('A')
     schema.addAttribute('A', 'X')
     schema.addAttribute('A', 'Y')
     schema.addAttribute('A', 'Z')
     model = Model(schema, ['[A].X -> [A].Z', '[A].Y -> [A].Z'])
     pc = PC(schema, Oracle(model))
     undirectedSkeleton = nx.DiGraph()
     relVarX = ParserUtil.parseRelVar('[A].X')
     relVarY = ParserUtil.parseRelVar('[A].Y')
     relVarZ = ParserUtil.parseRelVar('[A].Z')
     undirectedSkeleton.add_edges_from([(relVarX, relVarZ), (relVarZ, relVarX),
                                        (relVarY, relVarZ), (relVarZ, relVarY)])
     pc.setUndirectedSkeleton(undirectedSkeleton)
     pc.setSepsets({(relVarX, relVarY): set(), (relVarY, relVarX): set()})
     pc.pcPhaseII()
     self.assertPCOutputEqual(['[A].X', '[A].Y', '[A].Z'], [('[A].X', '[A].Z'), ('[A].Y', '[A].Z')],
                              None, None, pc.partiallyDirectedGraph, None, None)
Beispiel #25
0
    def testAddEntityAttribute(self):
        a = Entity('A')
        a.addAttribute('X', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(self, ['X'],
                                          [attr.name for attr in a.attributes])

        a.addAttribute('Y', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(self, ['X', 'Y'],
                                          [attr.name for attr in a.attributes])

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['X'],
            [attr.name for attr in schema.getEntity('A').attributes])

        schema.addAttribute('A', 'Y', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['X', 'Y'],
            [attr.name for attr in schema.getEntity('A').attributes])
Beispiel #26
0
    def testGenerateRelationshipAttributes(self):
        schema = SchemaGenerator.generateSchema(
            2,
            1,
            entityAttrDistribution=ConstantDistribution(0),
            relationshipAttrDistribution=ConstantDistribution(1),
            cardinalityDistribution=ConstantDistribution(Schema.ONE))
        expectedSchema = Schema()
        expectedSchema.addEntity('A')
        expectedSchema.addEntity('B')
        expectedSchema.addRelationship('AB', ('A', Schema.ONE),
                                       ('B', Schema.ONE))
        expectedSchema.addAttribute('AB', 'XY1')
        self.assertEqual(schema, expectedSchema)

        schema = SchemaGenerator.generateSchema(
            2,
            2,
            entityAttrDistribution=ConstantDistribution(0),
            relationshipAttrDistribution=ConstantDistribution(2),
            cardinalityDistribution=ConstantDistribution(Schema.ONE))
        expectedSchema.addRelationship('AB2', ('A', Schema.ONE),
                                       ('B', Schema.ONE))
        expectedSchema.addAttribute('AB', 'XY2')
        expectedSchema.addAttribute('AB2', 'XY2_1')
        expectedSchema.addAttribute('AB2', 'XY2_2')
        self.assertEqual(schema, expectedSchema)
Beispiel #27
0
    def testDependencyValidity(self):
        # Model needs to pass in mock for dependencyChecker, make sure gets called exactly once per dependency
        mockRelDepChecker = MagicMock(
            wraps=RelationalValidity.checkRelationalDependencyValidity)
        schema = Schema()
        dependencies = []
        Model(schema,
              dependencies,
              relationalDependencyChecker=mockRelDepChecker)
        self.assertEqual(0, mockRelDepChecker.call_count)

        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        schema.addAttribute('A', 'V')
        schema.addEntity('B')
        schema.addAttribute('B', 'Y')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY))
        schema.addEntity('C')
        schema.addAttribute('C', 'Z')
        schema.addAttribute('C', 'W')
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))

        dependencies = [
            '[B, AB, A].X -> [B].Y', '[C, BC, B].Y -> [C].Z', '[C].Z -> [C].W',
            '[A].X -> [A].V', '[A, AB, B, BC, C].W -> [A].V'
        ]
        mockRelDepChecker = MagicMock(
            wraps=RelationalValidity.checkRelationalDependencyValidity)
        Model(schema,
              dependencies,
              relationalDependencyChecker=mockRelDepChecker)
        self.assertEqual(5, mockRelDepChecker.call_count)
Beispiel #28
0
    def testNoExistenceVariables(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.ONE))
        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')

        hop0 = ['[A].X', '[B].Y', '[C].Z', '[AB].XY', '[BC].YZ']

        hop1 = ['[A, AB].XY', '[B, AB].XY', '[B, BC].YZ', '[C, BC].YZ', '[AB, A].X',
                '[AB, B].Y', '[BC, C].Z', '[BC, B].Y']

        hop2 = ['[A, AB, B].Y', '[B, AB, A].X', '[B, BC, C].Z', '[C, BC, B].Y', '[AB, A, AB].XY',
                '[AB, B, BC].YZ', '[BC, C, BC].YZ', '[BC, B, AB].XY']

        hop3 = ['[A, AB, B, BC].YZ', '[B, AB, A, AB].XY', '[B, BC, C, BC].YZ', '[C, BC, B, AB].XY',
                '[AB, A, AB, B].Y', '[AB, B, BC, C].Z', '[BC, C, BC, B].Y', '[BC, B, AB, A].X']

        relVars = RelationalSpace.getRelationalVariables(schema, 3)
        self.assertTrue(all([isinstance(relVar, RelationalVariable) for relVar in relVars]))
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2 + hop3, [str(relVar) for relVar in relVars])
Beispiel #29
0
def incompleteness_example():
    schema = Schema()
    schema.addEntity("E1")
    schema.addEntity("E2")
    schema.addEntity("E3")
    schema.addRelationship("R1", ("E1", Schema.ONE), ("E2", Schema.ONE))
    schema.addRelationship("R2", ("E2", Schema.ONE), ("E3", Schema.ONE))
    schema.addRelationship("R3", ("E2", Schema.ONE), ("E3", Schema.ONE))
    schema.addAttribute("R1", "X")
    schema.addAttribute("R2", "Y")
    schema.addAttribute("E2", "Z")

    d1 = RelationalDependency(RelationalVariable(["R2", "E2", "R1"], "X"),
                              RelationalVariable(["R2"], "Y"))
    d2 = RelationalDependency(
        RelationalVariable(["R2", "E3", "R3", "E2"], "Z"),
        RelationalVariable(["R2"], "Y"))
    d3 = RelationalDependency(
        RelationalVariable(["R1", "E2", "R2", "E3", "R3", "E2"], "Z"),
        RelationalVariable(["R1"], "X"))
    model = Model(schema, [d1, d2, d3])
    return schema, model
Beispiel #30
0
    def testAddRelationshipAttribute(self):
        ab = Relationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        ab.addAttribute('XY1', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['XY1'], [attr.name for attr in ab.attributes])

        ab.addAttribute('XY2', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['XY1', 'XY2'], [attr.name for attr in ab.attributes])

        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        schema.addAttribute('AB', 'XY1', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['XY1'],
            [attr.name for attr in schema.getRelationship('AB').attributes])

        schema.addAttribute('AB', 'XY2', Attribute.INTEGER)
        TestUtil.assertUnorderedListEqual(
            self, ['XY1', 'XY2'],
            [attr.name for attr in schema.getRelationship('AB').attributes])
Beispiel #31
0
    def testOneEntity(self):
        schema = Schema()
        schema.addEntity('A')
        model = ModelGenerator.generateModel(schema, 0, 0)
        self.assertIsInstance(model, Model)
        TestUtil.assertUnorderedListEqual(self, [], model.dependencies)

        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        dependencies = ['[A].X1 -> [A].X2', '[A].X2 -> [A].X1']
        model = ModelGenerator.generateModel(schema, 0, 1, dependencies=dependencies,
            randomPicker=lambda depsList, _: [depsList[0]])
        self.assertIsInstance(model, Model)
        TestUtil.assertUnorderedListEqual(self, ['[A].X1 -> [A].X2'], [str(dep) for dep in model.dependencies])

        model = ModelGenerator.generateModel(schema, 0, 1, dependencies=dependencies,
            randomPicker=lambda depsList, _: [depsList[-1]])
        self.assertIsInstance(model, Model)
        TestUtil.assertUnorderedListEqual(self, ['[A].X2 -> [A].X1'], [str(dep) for dep in model.dependencies])

        schema.addAttribute('A', 'X3')
        dependencies = ['[A].X1 -> [A].X2', '[A].X2 -> [A].X3', '[A].X2 -> [A].X1', '[A].X3 -> [A].X2',
                        '[A].X1 -> [A].X3', '[A].X3 -> [A].X1']
        model = ModelGenerator.generateModel(schema, 0, 2, dependencies=dependencies,
            randomPicker=lambda depsList, _: [depsList[0]])
        self.assertIsInstance(model, Model)
        TestUtil.assertUnorderedListEqual(self, ['[A].X1 -> [A].X2', '[A].X2 -> [A].X3'],
            [str(dep) for dep in model.dependencies])

        # tests that model iteratively attempts to add dependencies, throwing out those that create conflicts
        dependencies = ['[A].X1 -> [A].X2', '[A].X2 -> [A].X1', '[A].X2 -> [A].X3', '[A].X3 -> [A].X2',
                       '[A].X1 -> [A].X3', '[A].X3 -> [A].X1']
        model = ModelGenerator.generateModel(schema, 0, 2, dependencies=dependencies,
            randomPicker=lambda depsList, _: [depsList[0]])
        self.assertIsInstance(model, Model)
        TestUtil.assertUnorderedListEqual(self, ['[A].X1 -> [A].X2', '[A].X2 -> [A].X3'],
            [str(dep) for dep in model.dependencies])