Пример #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)
Пример #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)
Пример #3
0
    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])
Пример #4
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)
Пример #5
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', [])
Пример #6
0
    def testOneRelationshipOneToOne(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))

        relPaths = RelationalSpace.getRelationalPaths(schema, 0)
        hop0 = [['A'], ['B'], ['AB']]
        TestUtil.assertUnorderedListEqual(self, hop0, relPaths)

        relPaths = RelationalSpace.getRelationalPaths(schema, 1)
        hop1 = [['A', 'AB'], ['AB', 'A'], ['AB', 'B'], ['B', 'AB']]
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1, relPaths)

        schema = Schema()
        schema.addEntity('B')
        schema.addEntity('C')
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.ONE))

        relPaths = RelationalSpace.getRelationalPaths(schema, 0)
        hop0 = [['B'], ['C'], ['BC']]
        TestUtil.assertUnorderedListEqual(self, hop0, relPaths)

        relPaths = RelationalSpace.getRelationalPaths(schema, 1)
        hop1 = [['B', 'BC'], ['BC', 'B'], ['BC', 'C'], ['C', 'BC']]
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1, relPaths)

        relPaths = RelationalSpace.getRelationalPaths(schema, 2)
        hop2 = [['B', 'BC', 'C'], ['C', 'BC', 'B']]
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2, relPaths)

        relPaths = RelationalSpace.getRelationalPaths(schema, 3)
        hop3 = []
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2 + hop3,
                                          relPaths)
Пример #7
0
    def testCardinalities(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Bad cardinality for entity1 or entity2: xxxx one. Should be either Schema.ONE or Schema.MANY",
            schema.addRelationship, 'AB', ('A', 'xxxx'), ('B', Schema.ONE))
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Bad cardinality for entity1 or entity2: many xxxx. Should be either Schema.ONE or Schema.MANY",
            schema.addRelationship, 'AB', ('A', Schema.MANY), ('B', 'xxxx'))
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Bad cardinality for entity1 or entity2: xxxx many. Should be either Schema.ONE or Schema.MANY",
            schema.addRelationship, 'AB', ('A', 'xxxx'), ('B', Schema.MANY))
        TestUtil.assertRaisesMessage(
            self, Exception,
            "Bad cardinality for entity1 or entity2: one xxxx. Should be either Schema.ONE or Schema.MANY",
            schema.addRelationship, 'AB', ('A', Schema.ONE), ('B', 'xxxx'))

        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        ab = schema.getRelationship('AB')
        self.assertEqual(Schema.ONE, ab.getCardinality('A'))
        self.assertEqual(Schema.ONE, ab.getCardinality('B'))

        schema.addEntity('C')
        schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY))
        bc = schema.getRelationship('BC')
        self.assertEqual(Schema.ONE, bc.getCardinality('B'))
        self.assertEqual(Schema.MANY, bc.getCardinality('C'))
        TestUtil.assertRaisesMessage(
            self, Exception, "Entity 'A' does not exist for relationship 'BC'",
            bc.getCardinality, 'A')
Пример #8
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)
Пример #9
0
    def testCardinalities(self):
        schema = SchemaGenerator.generateSchema(
            2,
            1,
            entityAttrDistribution=ConstantDistribution(0),
            relationshipAttrDistribution=ConstantDistribution(0),
            cardinalityDistribution=ConstantDistribution(Schema.ONE))
        expectedSchema = Schema()
        expectedSchema.addEntity('A')
        expectedSchema.addEntity('B')
        expectedSchema.addRelationship('AB', ('A', Schema.ONE),
                                       ('B', Schema.ONE))
        self.assertEqual(schema, expectedSchema)

        schema = SchemaGenerator.generateSchema(
            2,
            1,
            entityAttrDistribution=ConstantDistribution(0),
            relationshipAttrDistribution=ConstantDistribution(0),
            cardinalityDistribution=ConstantDistribution(Schema.MANY))
        expectedSchema = Schema()
        expectedSchema.addEntity('A')
        expectedSchema.addEntity('B')
        expectedSchema.addRelationship('AB', ('A', Schema.MANY),
                                       ('B', Schema.MANY))
        self.assertEqual(schema, expectedSchema)
Пример #10
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)
Пример #11
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)
Пример #12
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'], [], [])
Пример #13
0
    def testGetSchemaItems(self):
        schema = Schema()
        schema.addEntity('A')
        actualItems = schema.getSchemaItems()
        TestUtil.assertUnorderedListEqual(self, ['A'],
                                          [item.name for item in actualItems])
        actualItem = schema.getSchemaItem('A')
        self.assertEqual('A', actualItem.name)
        self.assertTrue(schema.hasSchemaItem('A'))

        schema.addEntity('B')
        actualItems = schema.getSchemaItems()
        TestUtil.assertUnorderedListEqual(self, ['A', 'B'],
                                          [item.name for item in actualItems])
        actualItem = schema.getSchemaItem('B')
        self.assertEqual('B', actualItem.name)
        self.assertTrue(schema.hasSchemaItem('B'))

        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE))
        actualItems = schema.getSchemaItems()
        TestUtil.assertUnorderedListEqual(self, ['A', 'B', 'AB'],
                                          [item.name for item in actualItems])
        actualItem = schema.getSchemaItem('AB')
        self.assertEqual('AB', actualItem.name)
        self.assertTrue(schema.hasSchemaItem('AB'))

        TestUtil.assertRaisesMessage(self, Exception,
                                     "Schema item 'XX' does not exist",
                                     schema.getSchemaItem, 'XX')
        self.assertFalse(schema.hasSchemaItem('XX'))
Пример #14
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])
Пример #15
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)
Пример #16
0
    def testPhaseI(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X')
        model = Model(schema, [])
        mockOracle = MagicMock(wraps=Oracle(model))
        mockModelProperty = PropertyMock()
        type(mockOracle).model = mockModelProperty
        pc = PC(schema, mockOracle)
        pc.pcPhaseI()
        self.assertEqual(0, mockModelProperty.call_count)   # forces us not to cheat by simply returning the model
        self.assertPCOutputEqual(['[A].X'], [], {}, 0, pc.undirectedSkeleton, pc.sepsets, mockOracle)

        schema.addAttribute('A', 'Y')
        model = Model(schema, [])
        mockOracle = MagicMock(wraps=Oracle(model))
        mockModelProperty = PropertyMock()
        type(mockOracle).model = mockModelProperty
        pc = PC(schema, mockOracle)
        pc.pcPhaseI()
        self.assertEqual(0, mockModelProperty.call_count)   # forces us not to cheat by simply returning the model
        expectedSepset = {('[A].X', '[A].Y'): set(), ('[A].Y', '[A].X'): set()}
        self.assertPCOutputEqual(['[A].X', '[A].Y'], [], expectedSepset, 1, pc.undirectedSkeleton,
                                 pc.sepsets, mockOracle)

        model = Model(schema, ['[A].X -> [A].Y'])
        mockOracle = MagicMock(wraps=Oracle(model))
        pc = PC(schema, mockOracle)
        pc.pcPhaseI()
        expectedNodes = ['[A].X', '[A].Y']
        expectedEdges = [('[A].X', '[A].Y'), ('[A].Y', '[A].X')]
        self.assertPCOutputEqual(expectedNodes, expectedEdges, {}, 2, pc.undirectedSkeleton,
                                 pc.sepsets, mockOracle)

        schema.addAttribute('A', 'Z')
        model = Model(schema, ['[A].X -> [A].Y'])
        mockOracle = MagicMock(wraps=Oracle(model))
        pc = PC(schema, mockOracle)
        pc.pcPhaseI()
        expectedNodes = ['[A].X', '[A].Y', '[A].Z']
        expectedEdges = [('[A].X', '[A].Y'), ('[A].Y', '[A].X')]
        expectedSepset = {('[A].X', '[A].Z'): set(), ('[A].Z', '[A].X'): set(), ('[A].Y', '[A].Z'): set(),
                          ('[A].Z', '[A].Y'): set()}
        self.assertPCOutputEqual(expectedNodes, expectedEdges, expectedSepset, 4, pc.undirectedSkeleton,
                                 pc.sepsets, mockOracle)

        model = Model(schema, ['[A].X -> [A].Z', '[A].Z -> [A].Y'])
        mockOracle = MagicMock(wraps=Oracle(model))
        pc = PC(schema, mockOracle)
        pc.pcPhaseI()
        expectedNodes = ['[A].X', '[A].Y', '[A].Z']
        expectedEdges = [('[A].X', '[A].Z'), ('[A].Z', '[A].X'), ('[A].Z', '[A].Y'), ('[A].Y', '[A].Z')]
        expectedSepset = {('[A].X', '[A].Y'): {'[A].Z'}, ('[A].Y', '[A].X'): {'[A].Z'}}
        expectedDSepCount = 9

        self.assertPCOutputEqual(expectedNodes, expectedEdges, expectedSepset, expectedDSepCount, pc.undirectedSkeleton,
                                 pc.sepsets, mockOracle)
Пример #17
0
    def testTwoRelationships(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 = []

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

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

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

        relDeps = RelationalSpace.getRelationalDependencies(
            schema, 3, includeExistence=True)
        self.assertTrue(
            all([
                isinstance(relDep, RelationalDependency) for relDep in relDeps
            ]))
        TestUtil.assertUnorderedListEqual(self, hop0 + hop1 + hop2 + hop3,
                                          [str(relDep) for relDep in relDeps])
Пример #18
0
    def testSchemaEntities(self):
        schemaWithEntityA = Schema()
        schemaWithEntityA.addEntity('A')
        actualEntities = schemaWithEntityA.getEntities()
        TestUtil.assertUnorderedListEqual(self, ['A'],
                                          [ent.name for ent in actualEntities])

        schemaWithEntityA.addEntity('B')
        actualEntities = schemaWithEntityA.getEntities()
        TestUtil.assertUnorderedListEqual(self, ['A', 'B'],
                                          [ent.name for ent in actualEntities])
Пример #19
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]])
Пример #20
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']))
Пример #21
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']))
Пример #22
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),
                                       [])
Пример #23
0
    def testOneRelationshipManyToOne(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addEntity('B')
        schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.MANY))

        relPaths = RelationalSpace.getRelationalPaths(schema, 3)
        hopUpTo3 = [['A'], ['B'], ['AB'], ['A', 'AB'], ['AB',
                                                        'A'], ['AB', 'B'],
                    ['B', 'AB'], ['A', 'AB', 'B'], ['AB', 'B', 'AB'],
                    ['B', 'AB', 'A'], ['A', 'AB', 'B', 'AB'],
                    ['AB', 'B', 'AB', 'A']]
        TestUtil.assertUnorderedListEqual(self, hopUpTo3, relPaths)
Пример #24
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)
Пример #25
0
 def testBadHopThresholdInput(self):
     # hop thresholds must be non-negative integers
     schema = Schema()
     schema.addEntity('A')
     model = Model(schema, [])
     TestUtil.assertRaisesMessage(
         self, Exception, "hopThreshold must be a non-negative integer",
         AbstractGroundGraph, model, 'A', None)
     TestUtil.assertRaisesMessage(
         self, Exception, "hopThreshold must be a non-negative integer",
         AbstractGroundGraph, model, 'A', 1.5)
     TestUtil.assertRaisesMessage(
         self, Exception, "hopThreshold must be a non-negative integer",
         AbstractGroundGraph, model, 'A', -1)
Пример #26
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'], []))
Пример #27
0
    def testGenerateEntities(self):
        schema = SchemaGenerator.generateSchema(0, 0)
        expectedSchema = Schema()
        self.assertEqual(schema, expectedSchema)

        schema = SchemaGenerator.generateSchema(
            1, 0, entityAttrDistribution=ConstantDistribution(0))
        expectedSchema.addEntity('A')
        self.assertEqual(schema, expectedSchema)

        schema = SchemaGenerator.generateSchema(
            2, 0, entityAttrDistribution=ConstantDistribution(0))
        expectedSchema.addEntity('B')
        self.assertEqual(schema, expectedSchema)
Пример #28
0
    def testMaximumNumParentsArgument(self):
        schema = Schema()
        schema.addEntity('A')
        schema.addAttribute('A', 'X1')
        schema.addAttribute('A', 'X2')
        schema.addAttribute('A', 'X3')
        dependencies = ['[A].X1 -> [A].X3', '[A].X2 -> [A].X3']
        TestUtil.assertRaisesMessage(self, Exception, "Could not generate a model: failed to find a model with 2 dependenc[y|ies]",
                                     ModelGenerator.generateModel, schema, 0, 2, maxNumParents=1, dependencies=dependencies)

        schema.addAttribute('A', 'X4')
        dependencies = ['[A].X1 -> [A].X3', '[A].X2 -> [A].X3', '[A].X4 -> [A].X3']
        TestUtil.assertRaisesMessage(self, Exception, "Could not generate a model: failed to find a model with 3 dependenc[y|ies]",
                                     ModelGenerator.generateModel, schema, 0, 3, maxNumParents=2, dependencies=dependencies)
Пример #29
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'], []))
Пример #30
0
    def testGenerateEntityAttributes(self):
        schema = SchemaGenerator.generateSchema(
            1, 0, entityAttrDistribution=ConstantDistribution(1))
        expectedSchema = Schema()
        expectedSchema.addEntity('A')
        expectedSchema.addAttribute('A', 'X1')
        self.assertEqual(schema, expectedSchema)

        schema = SchemaGenerator.generateSchema(
            2, 0, entityAttrDistribution=ConstantDistribution(2))
        expectedSchema.addEntity('B')
        expectedSchema.addAttribute('A', 'X2')
        expectedSchema.addAttribute('B', 'Y1')
        expectedSchema.addAttribute('B', 'Y2')
        self.assertEqual(schema, expectedSchema)
Пример #31
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