Beispiel #1
0
    def support_exist(self, expr1, expr2, lst=False):
        if ((expr1 is None) or (expr1 == "")) or ((expr2 is None) or
                                                  (expr2 == "")):
            return [] if lst else None

        variables = re.sub('[~\&\|\(\)]', ' ', expr1 + expr2)
        variables = re.sub(' +', ' ', variables.strip())
        variables = variables.split(" ")

        bdd = BDD()
        for var in variables:
            bdd.add_var(var)

        expr1 = bdd.add_expr(expr1)
        expr2 = bdd.add_expr(expr2)
        u = bdd.exist(bdd.support(expr1), expr2)

        dnf = self.__get_dnf(bdd, u)

        conj = []
        for el in dnf:
            if el[0] is True:
                el = el[1:]
                el.reverse()
                conj.append("(%s)" % " & ".join(el))

        if lst:
            return conj

        return " | ".join(conj)
Beispiel #2
0
    def simplify(self, strformula, lst=False):
        if (strformula is None) or (strformula == ""):
            return [] if lst else None
        variables = re.sub('[~\&\|\(\)]', ' ', strformula)
        variables = re.sub(' +', ' ', variables.strip())
        variables = variables.split(" ")

        bdd = BDD()
        for var in variables:
            bdd.add_var(var)

        u = bdd.add_expr(strformula)
        dnf = self.__get_dnf(bdd, u)

        conj = []
        for el in dnf:
            if el[0] is True:
                el = el[1:]
                el.reverse()
                conj.append("(%s)" % " & ".join(el))

        if lst:
            return conj

        return " | ".join(conj)
Beispiel #3
0
class RandomExploration:
    def __init__(self,
                 total_vars=10,
                 total_actions=10,
                 max_value=10,
                 with_bdd=False):
        self.total_vars = total_vars
        self.total_actions = total_actions
        self.aobs = AOBS()
        self.max_value = max_value
        self.bdd = BDD()
        self.bdd_expr = None
        self.bdd_var_names = [self.var_name(i) for i in range(self.total_vars)]
        self.with_bdd = with_bdd
        self.steps_made = 0
        self.belief_state_size_threshold = 1e6
        self.sizes_result = []
        # TODO: 0 <= values < self.max_value !

    @staticmethod
    def var_name(i):
        if i < 26:
            return chr(ord('a') + i)
        else:
            return RandomExploration.var_name(
                i // 26) + RandomExploration.var_name(i % 26)

    def initialize_aobs(self, physical_state):
        self.aobs.root = self.aobs.hash_recursive(
            ['a'] + [[i, v] for i, v in enumerate(physical_state)])

    def act_bdd(self, preconditions, action, bdd=None):
        bdd_precs = self.assignment_bdd(*zip(*preconditions))
        # print(bdd_precs.to_expr())
        # poss, negs = self.assignment_bdd_(*zip(*preconditions))
        # print("only poss or negs: ", (self.bdd_expr & poss).dag_size, (self.bdd_expr & negs).dag_size)
        # print("before prec size: ", self.bdd_expr.dag_size)
        # print("after prec size: ", (self.bdd_expr & bdd_precs).dag_size)
        if bdd is None:
            self.bdd_expr = (self.bdd_expr & ~bdd_precs) | self.act_on_bdd(
                self.bdd_expr & bdd_precs, action)
        else:
            return self.act_on_bdd(bdd & bdd_precs, action)

    def act_on_bdd(self, bdd, action):
        variables = list(zip(*action[1][1][1:]))[0]
        bdd_effects = (self.assignment_bdd(*zip(*effect[1:]))
                       for _, effect in action[1:])
        bdd_action = functools.reduce(operator.or_, bdd_effects)
        # print(variables)
        # print("size before: ", bdd.dag_size)
        bdd_cleaned = self.clean_vars_bdd(bdd, variables)
        # print("cleaned size: ", bdd_cleaned.dag_size)
        # print("after action size: ", (bdd_cleaned & bdd_action).dag_size)
        return bdd_cleaned & bdd_action

    def clean_vars_bdd(self, bdd, variables):
        # print("to clean: ", variables)
        bvars = (self.bdd_var_names[var] + str(val)
                 for var, val in itertools.product(variables,
                                                   range(self.max_value)))
        for bv in bvars:
            bdd = self.bdd.let({bv: True}, bdd) | self.bdd.let({bv: False},
                                                               bdd)
        return bdd

    def assignment_bdd(self, vars, vals):
        kvs = {v: u for v, u in zip(vars, vals)}
        # print("vars: ", vars)
        # print("vals: ", vals)

        bvars = list(self.bdd_var_names[var] + str(val)
                     for var, val in zip(vars, vals))
        # print(bvars)
        positives = functools.reduce(operator.and_, (self.bdd.add_expr(bvar)
                                                     for bvar in bvars))
        negatives_bvars = list(
            self.bdd_var_names[var] + str(val)
            for var, val in itertools.product(vars, range(self.max_value))
            if kvs[var] != val)
        # print(negatives_bvars)
        negatives = functools.reduce(operator.and_,
                                     (~self.bdd.add_expr(bvar)
                                      for bvar in negatives_bvars))
        return positives & negatives

    def assignment_bdd_(self, vars, vals):
        kvs = {v: u for v, u in zip(vars, vals)}
        # print("vars: ", vars)
        # print("vals: ", vals)

        bvars = list(self.bdd_var_names[var] + str(val)
                     for var, val in zip(vars, vals))
        # print(bvars)
        positives = functools.reduce(operator.and_, (self.bdd.add_expr(bvar)
                                                     for bvar in bvars))
        negatives_bvars = list(
            self.bdd_var_names[var] + str(val)
            for var, val in itertools.product(vars, range(self.max_value))
            if kvs[var] != val)
        # print(negatives_bvars)
        negatives = functools.reduce(operator.and_,
                                     (~self.bdd.add_expr(bvar)
                                      for bvar in negatives_bvars))
        return positives, negatives

    def initialize_bdd(self, physical_state):
        for var, val in itertools.product(self.bdd_var_names,
                                          range(self.max_value)):
            self.bdd.add_var(var + str(val))
        self.bdd_expr = self.assignment_bdd(*zip(*enumerate(physical_state)))

    def random_init(self):
        ps = [
            random.randint(0, self.max_value - 1)
            for _ in range(self.total_vars)
        ]
        self.initialize_aobs(ps)
        if self.with_bdd:
            self.initialize_bdd(ps)
        return ps

    def generate_random_action(self, precs, total, each):
        preconds = {}
        while len(preconds) < precs:
            preconds[random.randint(0, self.total_vars - 1)] = random.randint(
                0, self.max_value - 1)
        preconditions = [(var, lambda v, val=val: v == val)
                         for var, val in preconds.items()]
        preconditions_bdd = list(preconds.items())
        eff_vars = set()
        while len(eff_vars) < each:
            eff_vars.add(random.randint(0, self.total_vars - 1))
        probs = [random.random() for _ in range(total)]
        norm = sum(probs)
        probs = [p / norm for p in probs]
        action = ['o'] + [
            (p, ['a'] + [[v, random.randint(0, self.max_value - 1)]
                         for v in eff_vars]) for p in probs
        ]
        return preconditions, action, preconditions_bdd

    def random_exploration(self,
                           steps=20,
                           precs=3,
                           effects=3,
                           each=2,
                           each_step=False):
        initial_state = self.random_init()
        actions_applied = []
        j = 0
        self.steps_made = 0
        while len(actions_applied) < steps:
            preconditions, action, preconditions_bdd = self.generate_random_action(
                precs, effects, each)
            if self.aobs.prob(preconditions) > 0:
                # print("aobs nodes before: ", self.aobs.dag_size())
                self.aobs.act(preconditions, action)
                # print("aobs nodes after: ", self.aobs.dag_size())
                # print("aobs states: ", self.aobs.count_physical_states_real())
                if self.with_bdd:
                    self.act_bdd(preconditions_bdd, action)
                actions_applied.append((preconditions_bdd, action))
                j = 0
                self.steps_made = len(actions_applied)
                if each_step:
                    self.sizes_result.append(
                        dict(total=self.total_vars *
                             self.aobs.count_physical_states_real(),
                             aobs=self.aobs.dag_size(),
                             aobs_greedy=self.aobs.size_after_greedy(
                                 include_prob=True),
                             total_naive_dup=self.aobs.
                             estimate_number_of_states() * self.total_vars,
                             bdd=self.bdd_expr.dag_size))
                if self.aobs.estimate_number_of_states(
                ) * self.total_vars > self.belief_state_size_threshold:
                    return True
                # print(len(actions_applied))
            else:
                j += 1
                if j > 10000:
                    return False
        return True