def test_precision(self):
        print(">> ContinuumLogicProgram.precision(expected, predicted)")

        self.assertEqual(ContinuumLogicProgram.precision([],[]), 1.0)

        # Equal programs
        for i in range(self.__nb_unit_test):
            variables, domains = self.random_system()
            nb_states = random.randint(1,100)

            expected = []
            predicted = []

            for j in range(nb_states):
                s1 = [ random.uniform(d.get_min_value(),d.get_max_value()) for d in domains ]
                s2 = [ random.uniform(d.get_min_value(),d.get_max_value()) for d in domains  ]
                s2_ = [ Continuum.random(d.get_min_value(), d.get_max_value()) for d in domains ]

                expected.append( (s1,s2) )
                predicted.append( (s1,s2_) )

            precision = ContinuumLogicProgram.precision(expected, predicted)

            error = 0
            for j in range(len(expected)):
                s1, s2 = expected[j]
                s1_, s2_ = predicted[j]

                for k in range(len(s2)):
                    if not s2_[k].includes(s2[k]):
                        error += 1

            total = nb_states * len(variables)

            self.assertEqual( precision, 1.0 - (error / total) )

            #eprint("precision: ", precision)

            # error of size
            state_id = random.randint(0, len(expected)-1)
            modif = random.randint(1,len(expected[state_id]))
            expected[state_id] = ( expected[state_id][0][:-modif], expected[state_id][1] )

            self.assertRaises(ValueError, ContinuumLogicProgram.precision, expected, predicted)
示例#2
0
    def random_program(self, variables=None, domains=None):
        if variables is None:
            variables, domains = self.random_system()
        rules = []

        for j in range(random.randint(0, self.__nb_rules)):
            r = self.random_rule(variables, domains)
            rules.append(r)

        return ContinuumLogicProgram(variables, domains, rules)
    def test___init__(self):
        print(">> ContinuumLogicProgram.__init__(self, variables, domains, rules)")

        for i in range(self.__nb_unit_test):
            variables, domains = self.random_system()
            rules = []

            for j in range(random.randint(0,self.__nb_rules)):
                r = self.random_rule(variables, domains)
                rules.append(r)

            p = ContinuumLogicProgram(variables, domains, rules)

            self.assertEqual(p.get_variables(), variables)
            self.assertEqual(p.get_domains(), domains)
            self.assertEqual(p.get_rules(), rules)

            modif = random.randint(1,len(variables))
            self.assertRaises(ValueError, ContinuumLogicProgram, variables, domains[:-modif], rules)
            for var in range(0, modif):
                domains.append(Continuum.random(self.__min_value, self.__max_value, self.__min_domain_size))
            self.assertRaises(ValueError, ContinuumLogicProgram, variables, domains, rules)
示例#4
0
    def test_fit(self):
        eprint(">> ACEDIA.fit(variables, values, transitions)")

        for i in range(self.__nb_unit_test):

            eprint("\rTest ", i + 1, "/", self.__nb_unit_test, end='')

            # Generate transitions
            epsilon = random.choice([0.1, 0.25, 0.3, 0.5])
            variables, domains = self.random_system()
            p = ContinuumLogicProgram.random(variables, domains, 1,
                                             len(variables), epsilon)

            #eprint("Progam: ", p)

            # Valid and realistic epsilon
            #epsilon = round(random.uniform(0.1,1.0), 2)
            #while epsilon == 1.0:
            #    epsilon = round(random.uniform(0.1,1.0), 2)

            t = p.generate_all_transitions(epsilon)

            #sys.exit()

            #eprint("Transitions: ")
            #for s1, s2 in t:
            #    eprint(s1, s2)
            #eprint("Transitions: ", t)

            p_ = ACEDIA.fit(p.get_variables(), p.get_domains(), t)
            rules = p_.get_rules()

            #eprint("learned: ", p_)

            # All transitions are realized
            #------------------------------

            for head_var in range(len(p.get_variables())):
                for s1, s2 in t:
                    for idx, val in enumerate(s2):
                        realized = 0
                        for r in rules:
                            if r.get_head_variable(
                            ) == idx and r.get_head_value().includes(
                                    val) and r.matches(s1):
                                realized += 1
                                break
                        if realized <= 0:
                            eprint("head_var: ", head_var)
                            eprint("s1: ", s1)
                            eprint("s2: ", s2)
                            eprint("learned: ", p_)
                        self.assertTrue(
                            realized >= 1)  # One rule realize the example

            # All rules are minimals
            #------------------------
            for r in rules:

                #eprint("r: ", r)

                # Try reducing head min
                #-----------------------
                r_ = r.copy()
                h = r_.get_head_value()
                if h.get_min_value() + epsilon <= h.get_max_value():
                    r_.set_head_value(
                        Continuum(h.get_min_value() + epsilon,
                                  h.get_max_value(), h.min_included(),
                                  h.max_included()))

                    #eprint("spec: ", r_)

                    conflict = False
                    for s1, s2 in t:
                        if not r_.get_head_value().includes(
                                s2[r_.get_head_variable()]) and r_.matches(
                                    s1):  # Cover a negative example
                            conflict = True
                            #eprint("conflict")
                            break

                    if not conflict:
                        eprint("Non minimal rule: ", r)
                        eprint("head can be specialized into: ",
                               r_.get_head_variable(), "=",
                               r_.get_head_value())

                    self.assertTrue(conflict)

                # Try reducing head max
                #-----------------------
                r_ = r.copy()
                h = r_.get_head_value()
                if h.get_max_value() - epsilon >= h.get_min_value():
                    r_.set_head_value(
                        Continuum(h.get_min_value(),
                                  h.get_max_value() - epsilon,
                                  h.min_included(), h.max_included()))

                    #eprint("spec: ", r_)

                    conflict = False
                    for s1, s2 in t:
                        if not r_.get_head_value().includes(
                                s2[r_.get_head_variable()]) and r_.matches(
                                    s1):  # Cover a negative example
                            conflict = True
                            #eprint("conflict")
                            break

                    if not conflict:
                        eprint("Non minimal rule: ", r)
                        eprint("head can be generalized to: ",
                               r_.get_head_variable(), "=",
                               r_.get_head_value())

                    self.assertTrue(conflict)

                # Try extending condition
                #-------------------------
                for (var, val) in r.get_body():

                    # Try extend min
                    r_ = r.copy()
                    if val.get_min_value(
                    ) - epsilon >= domains[var].get_min_value():
                        val_ = val.copy()
                        if not val_.min_included():
                            val_.set_lower_bound(val_.get_min_value(), True)
                        else:
                            val_.set_lower_bound(
                                val_.get_min_value() - epsilon, False)
                        r_.set_condition(var, val_)

                        #eprint("gen: ", r_)

                        conflict = False
                        for s1, s2 in t:
                            if not r_.get_head_value().includes(
                                    s2[r_.get_head_variable()]) and r_.matches(
                                        s1):  # Cover a negative example
                                conflict = True
                                #eprint("conflict")
                                break

                        if not conflict:
                            eprint("Non minimal rule: ", r)
                            eprint("condition can be generalized: ", var, "=",
                                   val_)

                        self.assertTrue(conflict)

                    # Try extend max
                    r_ = r.copy()
                    if val.get_max_value(
                    ) + epsilon <= domains[var].get_max_value():
                        val_ = val.copy()
                        if not val_.max_included():
                            val_.set_upper_bound(val_.get_max_value(), True)
                        else:
                            val_.set_upper_bound(
                                val_.get_max_value() + epsilon, False)
                        r_.set_condition(var, val_)

                        #eprint("gen: ", r_)

                        conflict = False
                        for s1, s2 in t:
                            if not r_.get_head_value().includes(
                                    s2[r_.get_head_variable()]) and r_.matches(
                                        s1):  # Cover a negative example
                                conflict = True
                                #eprint("conflict")
                                break

                        if not conflict:
                            eprint("Non minimal rule: ", r)
                            eprint("condition can be generalized: ", var, "=",
                                   val_)

                        self.assertTrue(conflict)
        eprint()
    def test_random(self):
        print(">> ContinuumLogicProgram.random(variables, values, rule_min_size, rule_max_size, epsilon, delay=1)")

        # No delay
        for i in range(self.__nb_unit_test):
            variables, domains = self.random_system()

            min_body_size = 0
            max_body_size = random.randint(min_body_size, len(variables))

            # Valid and realistic epsilon
            epsilon = round(random.uniform(0.1,1.0), 2)
            while epsilon == 1.0:
                epsilon = round(random.uniform(0.1,1.0), 2)

            p = ContinuumLogicProgram.random(variables, domains, min_body_size, max_body_size, epsilon)
            #eprint(p.to_string())

            self.assertEqual(p.get_variables(), variables)
            self.assertEqual(p.get_domains(), domains)

            for r in p.get_rules():
                self.assertTrue(len(r.get_body()) >= min_body_size)
                self.assertTrue(len(r.get_body()) <= max_body_size)

            states = ContinuumLogicProgram.states(domains, epsilon)

            for s in states:
                for var in range(len(s)):
                    matched = False
                    conclusion = -1
                    for r in p.get_rules():
                        if r.get_head_variable() == var and r.matches(s):
                            matched = True
                            #if conclusion == -1: # stored first conclusion
                            #    conclusion = r.get_head_value()
                            #else: # check conflict
                            #    self.assertEqual(conclusion, r.get_head_value())
                    self.assertTrue(matched)
        # Delay
        for i in range(self.__nb_unit_test):
            variables, domains = self.random_system()

            min_body_size = 0
            max_body_size = random.randint(min_body_size, len(variables))
            delay = random.randint(1, self.__max_delay)

            # Valid and realistic epsilon
            epsilon = round(random.uniform(0.1,1.0), 2)
            while epsilon == 1.0:
                epsilon = round(random.uniform(0.1,1.0), 2)

            p = ContinuumLogicProgram.random(variables, domains, min_body_size, max_body_size, epsilon, delay)
            #eprint(p.logic_form())

            extended_variables = variables.copy()
            extended_domains = domains.copy()
            for d in range(1,delay):
                extended_variables += [var+"_"+str(d) for var in variables]
                extended_domains += domains

            self.assertEqual(p.get_variables(), variables)
            self.assertEqual(p.get_domains(), domains)

            for r in p.get_rules():
                self.assertTrue(len(r.get_body()) >= min_body_size)
                self.assertTrue(len(r.get_body()) <= max_body_size)

            states = ContinuumLogicProgram.states(extended_domains, epsilon)

            for s in states:
                for var in range(len(variables)):
                    matched = False
                    conclusion = -1
                    for r in p.get_rules():
                        if r.get_head_variable() == var and r.matches(s):
                            matched = True
                            break
                            #if conclusion == -1: # stored first conclusion
                            #    conclusion = r.get_head_value()
                            #else: # check conflict
                            #    self.assertEqual(conclusion, r.get_head_value())
                    #if not matched:
                        #eprint(s)
                        #eprint(p)
                    self.assertTrue(matched)
    def test_generate_all_transitions(self):
        print(">> ContinuumLogicProgram.generate_all_transitions(epsilon)")

        for i in range(self.__nb_unit_test):
            variables, domains = self.random_system()
            p = self.random_program(variables, domains)

            # bad epsilon
            epsilon = random.uniform(-100, 0)

            self.assertRaises(ValueError, p.generate_all_transitions, epsilon)

            epsilon = random.uniform(0, 0.1)
            while epsilon == 0.0 or epsilon == 0.1:
                epsilon = random.uniform(0, 0.1)
            self.assertRaises(ValueError, p.generate_all_transitions, epsilon)

            epsilon = random.uniform(1.0, 100)
            while epsilon == 1.0:
                epsilon = random.uniform(1.0, 100)

            self.assertRaises(ValueError, p.generate_all_transitions, epsilon)

            # Valid and realistic epsilon
            epsilon = round(random.uniform(self.__min_epsilon,1.0), 2)
            while epsilon == 1.0:
                epsilon = round(random.uniform(self.__min_epsilon,1.0), 2)
            #eprint("epsilon: ", epsilon)

            transitions = p.generate_all_transitions(epsilon)

            #eprint(p.to_string())
            #eprint("transitions: ", transitions)
            #eprint("Nb transitions: ", len(transitions))
            #eprint(transitions)

            # All initial state appears
            S = ContinuumLogicProgram.states(p.get_domains(), epsilon)
            init = [s1 for s1, s2 in transitions]
            #eprint("init: ", init)
            #eprint("S: ", S)
            #eprint()
            for s in S:
                s2 = p.next(s)
                if None in s2: # uncomplete states ignored
                    continue
                appears = False
                for s1 in init:
                    different = False
                    for idx in range(len(s1)):
                        if abs(s1[idx]-s[idx]) > 0.0001:
                            different = True
                            break

                        if not different:
                            appears = True
                            break

                self.assertTrue(appears)

            # All transitions appears and are valid
            for s1, s2 in transitions:

                # all transitions from s1
                S = p.next(s1)
                S = ContinuumLogicProgram.states(S, epsilon)

                # s2 is a transion of s1
                self.assertTrue(s2 in S)

                # All transitions from s1 appears
                for s3 in S:
                    self.assertTrue( [s1,s3] in transitions)