def test_multi_instance(self): at = AddTree() t = at.add_tree() t.split(t.root(), 0, 2) t.split(t.left(t.root()), 0, 1) t.split(t.right(t.root()), 0, 3) t.set_leaf_value(t.left(t.left(t.root())), 0.1) t.set_leaf_value(t.right(t.left(t.root())), 0.2) t.set_leaf_value(t.left(t.right(t.root())), 0.3) t.set_leaf_value(t.right(t.right(t.root())), 0.4) t = at.add_tree() t.split(t.root(), 0, 2) t.split(t.left(t.root()), 1, 1) t.split(t.right(t.root()), 1, 3) t.set_leaf_value(t.left(t.left(t.root())), 0.1) t.set_leaf_value(t.right(t.left(t.root())), 0.2) t.set_leaf_value(t.left(t.right(t.root())), -0.3) t.set_leaf_value(t.right(t.right(t.root())), -0.4) #print(at) dt = DomTree([(at, {}), (at, {})]) l0 = dt.get_leaf(dt.tree().root()) v = Verifier(l0, Backend()) v.add_all_trees() v.add_constraint(v.instance(0).fvar() > v.instance(1).fvar()) v.add_constraint(v.instance(1).fvar() > 0) v.add_constraint(v.instance(0).xvar(0) == v.instance(1).xvar(0)) v.add_constraint(v.instance(1).xvar(1) < 1) models = [] while v.check() == Verifier.Result.SAT: m = v.model() self.assertGreater(m[0]["f"], m[1]["f"]) self.assertGreater(m[1]["f"], 0.0) self.assertEqual(m[0]["xs"][0], m[1]["xs"][0]) self.assertLess(m[1]["xs"][1], 1.0) print("MODEL xs", m[0]["xs"], m[1]["xs"]) print(" ws", m[0]["ws"], m[1]["ws"]) print(" f", m[0]["f"], m[1]["f"]) models.append(m) fam = v.model_family(m) #print("FAM", fam) v.add_constraint( not_in_domain_constraint(v, fam[0], 0) | not_in_domain_constraint(v, fam[1], 1)) self.assertEqual(len(models), 2)
def __call__(self, lk, check_paths): v = Verifier(lk, Backend()) v.add_constraint(v.fvar() > 5.0) v.add_constraint( z3.PbLe([(v.xvar(fid).get(), 1) for fid in v.instance(0).feat_ids()], 50)) return v
def __call__(self, lk, check_paths): v = Verifier(lk, Backend()) v.add_constraint(v.fvar(instance=0) < 0.0) v.add_constraint(v.xvar(0, instance=0) > 50) v.add_constraint(v.xvar(1, instance=0) < 50) # instances are exactly the same! for fid1, fid2 in zip( v.instance(0).feat_ids(), v.instance(1).feat_ids()): v.add_constraint( v.xvar(fid1, instance=0) == v.xvar(fid2, instance=1)) v.add_constraint( v.fvar(instance=1).get() - v.fvar(instance=0).get() < 9999) return v
def test_mark_paths(self): at = AddTree() t = at.add_tree() t.split(t.root(), 0, 2) t.split(t.left(t.root()), 0, 1) t.split(t.right(t.root()), 0, 3) t.set_leaf_value(t.left(t.left(t.root())), 0.1) t.set_leaf_value(t.right(t.left(t.root())), 0.2) t.set_leaf_value(t.left(t.right(t.root())), 0.3) t.set_leaf_value(t.right(t.right(t.root())), 0.4) #print(at) dt = DomTree([(at, {0: RealDomain(0, 2)}), (at, {})]) l0 = dt.get_leaf(dt.tree().root()) v = Verifier(l0, Backend()) v.add_constraint(in_domain_constraint(v, l0.get_domains(0), instance=0)) v.add_constraint(v.xvar(0, instance=0) == v.xvar(0, instance=1)) self.assertFalse(l0.is_reachable(0, 0, 2)) self.assertTrue(l0.is_reachable(1, 0, 2)) v.instance(1).mark_unreachable_paths(0) v.add_constraint(v.xvar(0, instance=1) < 1.0) self.assertTrue(l0.is_reachable(0, 0, 4)) self.assertTrue(l0.is_reachable(1, 0, 4)) v.instance(0).mark_unreachable_paths(0, only_feat_id=999) v.instance(1).mark_unreachable_paths(0, only_feat_id=999) self.assertTrue(l0.is_reachable(0, 0, 4)) # no effect, wrong feat_id self.assertTrue(l0.is_reachable(1, 0, 4)) v.instance(0).mark_unreachable_paths(0, only_feat_id=0) v.instance(1).mark_unreachable_paths(0, only_feat_id=0) self.assertFalse(l0.is_reachable(0, 0, 4)) self.assertFalse(l0.is_reachable(1, 0, 4)) self.assertFalse(l0.is_reachable(1, 0, 2)) v.add_all_trees() #print(v._backend._solver) v.check() m = v.model() self.assertLess(m[0]["xs"][0], 1.0) self.assertGreaterEqual(m[0]["xs"][0], 0.0) self.assertEqual(m[0]["xs"][0], m[1]["xs"][0]) self.myAssertAlmostEqual(m[0]["ws"][0], 0.1)
def test_mark_paths2(self): at = AddTree.read("tests/models/xgb-img-easy.json") dt = DomTree(at, {}) l0 = dt.get_leaf(0) v = Verifier(l0, Backend()) v.add_constraint(v.fvar() < 0.0) v.add_constraint(v.xvar(0) > 50) v.add_constraint(v.xvar(0) <= 80) def test_reachable(m, l0): m(l0.is_reachable(0, 9, 109)) m(l0.is_reachable(0, 9, 117)) m(l0.is_reachable(0, 9, 95)) m(l0.is_reachable(0, 9, 104)) m(l0.is_reachable(0, 9, 83)) m(l0.is_reachable(0, 9, 70)) m(l0.is_reachable(0, 9, 52)) m(l0.is_reachable(0, 9, 37)) m(l0.is_reachable(0, 9, 5)) m(l0.is_reachable(0, 9, 29)) m(l0.is_reachable(0, 8, 96)) m(l0.is_reachable(0, 8, 3)) m(l0.is_reachable(0, 7, 23)) m(l0.is_reachable(0, 7, 15)) m(l0.is_reachable(0, 6, 118)) m(l0.is_reachable(0, 6, 98)) m(l0.is_reachable(0, 6, 37)) m(l0.is_reachable(0, 6, 5)) m(l0.is_reachable(0, 6, 29)) m(l0.is_reachable(0, 5, 112)) m(l0.is_reachable(0, 5, 90)) m(l0.is_reachable(0, 5, 66)) m(l0.is_reachable(0, 5, 3)) m(l0.is_reachable(0, 5, 37)) m(l0.is_reachable(0, 4, 84)) m(l0.is_reachable(0, 4, 70)) m(l0.is_reachable(0, 4, 53)) m(l0.is_reachable(0, 4, 37)) m(l0.is_reachable(0, 4, 5)) m(l0.is_reachable(0, 4, 29)) m(l0.is_reachable(0, 4, 23)) m(l0.is_reachable(0, 3, 108)) m(l0.is_reachable(0, 3, 92)) m(l0.is_reachable(0, 3, 84)) m(l0.is_reachable(0, 3, 78)) m(l0.is_reachable(0, 3, 3)) m(l0.is_reachable(0, 3, 49)) m(l0.is_reachable(0, 3, 43)) m(l0.is_reachable(0, 3, 37)) m(l0.is_reachable(0, 2, 96)) m(l0.is_reachable(0, 2, 80)) m(l0.is_reachable(0, 2, 66)) m(l0.is_reachable(0, 2, 3)) m(l0.is_reachable(0, 2, 49)) m(l0.is_reachable(0, 2, 37)) m(l0.is_reachable(0, 1, 94)) m(l0.is_reachable(0, 1, 82)) m(l0.is_reachable(0, 1, 66)) m(l0.is_reachable(0, 1, 3)) m(l0.is_reachable(0, 1, 35)) m(l0.is_reachable(0, 1, 23)) m(l0.is_reachable(0, 0, 98)) m(l0.is_reachable(0, 0, 86)) m(l0.is_reachable(0, 0, 29)) m(l0.is_reachable(0, 0, 5)) test_reachable(self.assertTrue, l0) for i in range(len(at)): v.instance(0).mark_unreachable_paths(i) test_reachable(self.assertFalse, l0)