Ejemplo n.º 1
0
 def get_truth_assignment(self, symbol):
     """
     get one set of truth assignment that makes the symbol true
     :param symbol: logical expression which controls the transition
     :return: a set of truth assignment enables the symbol
     """
     # empty symbol
     if symbol == '(1)':
         return '1'
     # non-empty symbol
     else:
         exp = symbol.replace('||', '|').replace('&&',
                                                 '&').replace('!', '~')
         # add extra constraints: a single robot can reside in at most one region
         robot_region = self.robot2region(exp)
         for robot, region in robot_region.items():
             mutual_execlusion = list(combinations(region, 2))
             # single label in the symbol
             if not mutual_execlusion: continue
             for i in range(len(mutual_execlusion)):
                 mutual_execlusion[i] = '(~(' + ' & '.join(
                     list(mutual_execlusion[i])) + '))'
             exp = exp + '&' + ' & '.join(mutual_execlusion)
         # find one truth assignment that makes symbol true using function satisfiable
         truth = satisfiable(sympify(exp), algorithm="dpll")
         try:
             truth_table = dict()
             for key, value in truth.items():
                 truth_table[key.name] = value
         except AttributeError:
             return False
         else:
             return truth_table
Ejemplo n.º 2
0
    def DelInfesEdge(self, robot):
        """
        Delete infeasible edge
        :param buchi_graph: buchi automaton
        :param robot: # robot
        """
        TobeDel = []
        # print(self.buchi_graph.number_of_edges())
        i = 0
        for edge in self.buchi_graph.edges():
            i = i+1
            # print(i)
            b_label = self.buchi_graph.edges[edge]['label']
            # multiple labels
            if ') && (' in b_label:
                TobeDel.append(edge)
                continue
            if b_label != '(1)':
                exp = b_label.replace('||', '|').replace('&&', '&').replace('!', '~')
                truth = satisfiable(exp, algorithm="dpll")
                truth_table = dict()
                for key, value in truth.items():
                    truth_table[key.name] = value
                if not truth_table:
                    TobeDel.append(edge)
                else:
                    self.buchi_graph.edges[edge]['truth'] = truth_table
            else:
                self.buchi_graph.edges[edge]['truth'] = '1'

        for edge in TobeDel:
            self.buchi_graph.remove_edge(edge[0], edge[1])
Ejemplo n.º 3
0
    def add_transition(self, transition: TransitionType) -> None:
        """
        Add a transition, i.e. a tuple (source, guard, destination).

        :param transition: the transition to add.
        :return: None
        :raise ValueError: if the source state does not exist.
        :raise ValueError: if the dest state does not exist.
        """
        state1, guard, state2 = transition
        assert state1 in self.states
        assert state2 in self.states
        if isinstance(guard, str):
            guard = simplify(parse_expr(guard))
        other_guard = self._transition_function.get(state1,
                                                    {}).get(state2, None)
        if other_guard is None:
            super().add_transition((state1, guard, state2))
        else:
            outgoing_guards = self._transition_function.get(state1,
                                                            {}).values()
            ors = sympy.Or(*outgoing_guards)
            all_outgoing_guards = sympy.And(ors, guard)
            if sympy.satisfiable(all_outgoing_guards) is False:
                super().add_transition((state1, guard, state2))
            else:
                raise ValueError("Transition is not deterministic.")
Ejemplo n.º 4
0
def inclusion(subtask_lib, subtask_new, tree, end2path):
    """
    whether subtask_lib is included in subtask_new
    :param subtask_lib:
    :param subtask_new:
    :return:
    """
    # trick
    # no need to build subtree for those who doesn't have self-loop and edge label != 1   []<> ( <>)
    if subtask_new[1].label == to_dnf(
            '0') and subtask_new[0].x != subtask_new[1].x:
        return 'zero'
    condition = not satisfiable(
        And(subtask_lib[1].label, Not(subtask_new[1].label)))
    if subtask_lib[0].x == subtask_new[0].x and subtask_lib[
            1].x == subtask_new[1].x:
        condition = condition or good_execution(
            end2path[(subtask_lib[0], subtask_lib[1])], subtask_new[1].label,
            tree)
        if condition:
            return 'forward'
    elif subtask_lib[0].x == subtask_new[1].x and subtask_lib[
            1].x == subtask_new[0].x:
        condition = condition or good_execution(
            end2path[(subtask_lib[0], subtask_lib[1])], subtask_new[1].label,
            tree)
        if condition:
            return 'backward'

    return ''
Ejemplo n.º 5
0
 def rsolve(self):
     A = self.INITA.copy()
     B = self.INITB.copy()
     C = self.INITC.copy()
     D = self.INITD.copy()
     eq = And(*[~(A[i] ^ self.a[i]) & ~(B[i] ^ self.b[i]) & ~(C[i] ^ self.c[i]) & ~(D[i] ^ self.d[i]) for i in range(32)])
     print("Equation:",eq)
     return satisfiable(eq)
Ejemplo n.º 6
0
    def determinize(self) -> "SymbolicDFA":
        """Do determinize."""
        macro_initial_state = frozenset([self._initial_state
                                         ])  # type: FrozenSet[int]
        stack = [macro_initial_state]
        visited = {macro_initial_state}
        macro_accepting_states = (
            {macro_initial_state} if
            macro_initial_state.intersection(self.accepting_states) != set()
            else set())  # type: Set[FrozenSet[int]]
        moves = set()

        # given an iterable of transitions (i.e. triples (source, guard, destination)),
        # get the guard
        def getguard(x):
            return map(operator.itemgetter(1), x)

        # given ... (as before)
        # get the target
        def gettarget(x):
            return map(operator.itemgetter(2), x)

        while len(stack) > 0:
            macro_source = stack.pop()
            transitions = set([
                (source, guard, dest) for source in macro_source
                for dest, guard in self._transition_function.get(source,
                                                                 {}).items()
            ])
            for transitions_subset in map(frozenset,
                                          iter_powerset(transitions)):
                if len(transitions_subset) == 0:
                    continue
                transitions_subset_negated = transitions.difference(
                    transitions_subset)
                phi_positive = And(*getguard(transitions_subset))
                phi_negative = And(
                    *map(Not, getguard(transitions_subset_negated)))
                phi = phi_positive & phi_negative
                if sympy.satisfiable(phi) is not False:
                    macro_dest = frozenset(
                        gettarget(transitions_subset))  # type: FrozenSet[int]
                    moves.add((macro_source, phi, macro_dest))
                    if macro_dest not in visited:
                        visited.add(macro_dest)
                        stack.append(macro_dest)
                        if macro_dest.intersection(
                                self.accepting_states) != set():
                            macro_accepting_states.add(macro_dest)

        return self._from_transitions(visited, macro_initial_state,
                                      set(macro_accepting_states), moves)
Ejemplo n.º 7
0
 def greatest_fixpoint_condition(el: Tuple[int, int], current_set: Set):
     """Condition to say whether the pair must be removed from the bisimulation relation."""
     # unpack the two states
     s_source, t_source = el
     for (s_dest,
          s_guard) in dfa._transition_function.get(s_source,
                                                   {}).items():
         for (t_dest,
              t_guard) in dfa._transition_function.get(t_source,
                                                       {}).items():
             if (t_dest != s_dest
                     and (s_dest, t_dest) not in current_set and
                     satisfiable(And(s_guard, t_guard)) is not False):
                 return True
Ejemplo n.º 8
0
def satsolver_main():
    prop = open('/home/wrick/Documents/logia/prop', 'r').readline().strip()    # of the form -- Proposition name : forall p q r :Prop, expression.
    expr = prop.split(',')[-1].strip('.').strip()                              # expression without leading space or trailing .
    varnames = prop.split(':')[1].strip()[7:].replace(' ', ',')                # store the names of the variables as a string, split with ','
    varlist = list(symbols(varnames))                                          # create and store the symbols themselves in a list --- ERROR!!! symbols is not iterable 

    try:
        models = []
        sat = satisfiable(expr, all_models = True)
        while True:
            models.append(next(sat))
    except StopIteration:
        pass

    return(models)
Ejemplo n.º 9
0
def inclusion(subtask_lib, subtask_new):
    """
    whether subtask_lib is included in subtask_new
    :param subtask_lib:
    :param subtask_new:
    :return:
    """

    # if Equivalent(subtask_lib[0].label, subtask_new[0].label):
    #     print(subtask_lib[0].label, subtask_new[0].label)
    # A included in B <=> does no exist a truth assignment such that  (A & not B) is true
    if not satisfiable(And(subtask_lib[0].label, Not(subtask_new[0].label))):
        if subtask_lib[0].x == subtask_new[0].x and subtask_lib[1].x == subtask_new[1].x:
            return 'forward'
        elif subtask_lib[0].x == subtask_new[1].x and subtask_lib[1].x == subtask_new[0].x:
            return 'backward'

    return ''
Ejemplo n.º 10
0
    def is_complete(self) -> bool:
        """
        Check whether the automaton is complete.

        :return: True if the automaton is complete, False otherwise.
        """
        # all the state must have an outgoing transition.
        if not all(state in self._transition_function.keys()
                   for state in self.states):
            return False

        for source in self._transition_function:
            guards = self._transition_function[source].values()
            negated_guards = Not(Or(*guards))
            if satisfiable(negated_guards):
                return False

        return True
Ejemplo n.º 11
0
def target(exp, regions):
    """
    find the target location
    :param label: word
    :return: target location/region
    """

    target = []

    if exp != to_dnf('1'):
        # a set of target points
        for dnf in exp.args or [exp]:
            truth_table = satisfiable(dnf, algorithm="dpll")
            # find the target point with true value
            for key, value in truth_table.items():
                if value:
                    des = key.name.split('_')[0]
                    target.append(regions[des])
        return target
Ejemplo n.º 12
0
def models_with_all_atoms(formula, atoms):
    """Takes a formula and a set of atoms (that do not necessarily appear in the formula), 
    and returns a set of *models* of the formula, where each model is represented by a 
    *dictionary* that maps each atom to a Boolean value, where atoms are drawn from the 
    set of atoms that appear in ``formula`` *and* the set of atoms represented by ``atoms``.

    Parameters
    ----------
    formula : A Sympy formula.
    atoms : A set of Sympy atoms.

    Example
    -------
    >>> p,q,r = [eb.parse_formula(letter) for letter in "pqr"]
    >>> f = p | q
    >>> eb.models_with_all_atoms(f, {p,q})
    [{p: True, q: True}, 
     {p: True, q: False},
     {p: False, q: True}]
    >>> eb.models_with_all_atoms(f, {p,q,r})
    [{p: True, q: True, r: True}, 
     {p: True, q: True, r: False},
     {p: True, q: False, r: True},
     {p: True, q: False, r: False},
     {p: False, q: True, r: True},
     {p: False, q: True, r: False}]
    """
    if formula == True:
        return [model for model in tablize(atoms)]

    original_models = [model for model in satisfiable(formula, all_models=True)]
    extra_atoms = atoms - formula.atoms()

    if not extra_atoms:
        return original_models
    else:
        models_all_atoms = []
        for model in original_models:
            models_all_atoms += [updated_model for updated_model in tablize(extra_atoms, model)]
        return models_all_atoms
Ejemplo n.º 13
0
def inclusion(subtask_lib, subtask_new, tree, end2path):
    """
    whether subtask_lib is included in subtask_new
    :param subtask_lib:
    :param subtask_new:
    :return:
    """

    # if Equivalent(subtask_lib[0].label, subtask_new[0].label):
    #     print(subtask_lib[0].label, subtask_new[0].label)
    # A included in B <=> does no exist a truth assignment such that  (A & not B) is true
    # if not satisfiable(And(subtask_lib[0].label, Not(subtask_new[0].label))):
    #     if subtask_lib[0].x == subtask_new[0].x and subtask_lib[1].x == subtask_new[1].x:
    #         return 'forward'
    #     elif subtask_lib[0].x == subtask_new[1].x and subtask_lib[1].x == subtask_new[0].x:
    #         return 'backward'
    #
    # return ''

    # if subtask_new[0].label == to_dnf('0'):
    #     return 'zero'
    condition = not satisfiable(
        And(subtask_lib[0].label, Not(subtask_new[0].label)))
    if subtask_lib[0].x == subtask_new[0].x and subtask_lib[
            1].x == subtask_new[1].x:
        condition = condition or good_execution(
            end2path[(subtask_lib[0], subtask_lib[1])], subtask_new[0].label,
            tree)
        if condition:
            return 'forward'
    elif subtask_lib[0].x == subtask_new[1].x and subtask_lib[
            1].x == subtask_new[0].x:
        condition = condition or good_execution(
            end2path[(subtask_lib[0], subtask_lib[1])], subtask_new[0].label,
            tree)
        if condition:
            return 'backward'

    return ''
Ejemplo n.º 14
0
    def complete(self) -> "SymbolicAutomaton":
        """Complete the automaton."""
        states = set(self.states)
        initial_state = self.initial_state
        final_states = self.accepting_states
        transitions = set()
        sink_state = None
        for source in states:
            transitions_from_source = self._transition_function.get(source, {})
            transitions.update(
                set(
                    map(lambda x: (source, x[1], x[0]),
                        transitions_from_source.items())))
            guards = transitions_from_source.values()
            guards_negation = simplify(Not(Or(*guards)))
            if satisfiable(guards_negation) is not False:
                sink_state = len(states) if sink_state is None else sink_state
                transitions.add((source, guards_negation, sink_state))

        if sink_state is not None:
            states.add(sink_state)
            transitions.add((sink_state, BooleanTrue(), sink_state))
        return SymbolicAutomaton._from_transitions(states, initial_state,
                                                   final_states, transitions)
Ejemplo n.º 15
0
from sympy import pprint, satisfiable, to_cnf, simplify
import networkx as nx
import equibel as eb

def print_formulas(G):
    for node in G.nodes():
        print("Node {}:".format(node))
        pprint(G.formula_conj(node))
        #pprint(simplify(G.formula_conj(node)))
        #pprint(to_cnf(G.formula_conj(node), simplify=True))
    print("\n")
        

if __name__ == '__main__':
    G = eb.path_graph(5)
    G.add_formula(2, '(x1 & ~x4) | (x4 & ~x1) | ~x5')
    G.add_formula(3, 'x4 | ~x2 | ~x3')
    G.add_formula(4, '~x3 & (x4 | ~x5) & (x5 | ~x4)')

    print_formulas(G)

    G, num_iterations = eb.iterate_steady(G)
    print_formulas(G)

    print(G.formula_conj(0))
    for model in satisfiable(G.formula_conj(0), all_models=True):
        print(model)

    print("Num iterations = {}".format(num_iterations))
Ejemplo n.º 16
0
def _make_transition(marco_q: FrozenSet[FrozenSet[PLAtomic]],
                     i: PropositionalInterpretation):
    new_macrostate = set()

    for q in marco_q:
        # delta function applied to every formula in the macro state Q
        delta_formulas = [cast(Delta, f.s).delta(i) for f in q]

        # find atomics -> so also ldlf formulas
        # replace atomic with custom object
        # convert to sympy

        # find the list of atoms, which are "true" atoms
        # (i.e. propositional atoms) or LDLf formulas
        atomics = [s for subf in delta_formulas for s in find_atomics(subf)]

        atom2id = {v: str(k)
                   for k, v in enumerate(atomics)}  # type: Dict[PLAtomic, str]
        id2atom = {v: k
                   for k, v in atom2id.items()}  # type: Dict[str, PLAtomic]

        # build a map from formula to a "freezed" propositional Atomic Formula
        formula2atomic_formulas = {
            f: PLAtomic(atom2id[f]) if f != PLTrue()
            and f != PLFalse()  # and not isinstance(f, PLAtomic)
            else f
            for f in atomics
        }

        # the final list of Propositional Atomic Formulas,
        # one for each formula in the original macro state Q
        transformed_delta_formulas = [
            _transform_delta(f, formula2atomic_formulas)
            for f in delta_formulas
        ]

        # the empty conjunction stands for true
        if len(transformed_delta_formulas) == 0:
            conjunctions = PLTrue()
        elif len(transformed_delta_formulas) == 1:
            conjunctions = transformed_delta_formulas[0]
        else:
            conjunctions = PLAnd(transformed_delta_formulas)  # type: ignore

        # the model in this case is the smallest set of symbols
        # s.t. the conjunction of "freezed" atomic formula is true.
        # alphabet = frozenset(symbol2formula)
        # models = frozenset(conjunctions.minimal_models(alphabet))

        formula = to_sympy(conjunctions, replace=atom2id)  # type: ignore
        all_models = list(sympy.satisfiable(formula, all_models=True))
        if len(all_models) == 1 and all_models[0] == BooleanFalse():
            models = []  # type: List[Set[str]]
        elif len(all_models) == 1 and all_models[0] == {True: True}:
            models = [set()]
        else:
            models = list(
                map(lambda x: {k
                               for k, v in x.items()
                               if v is True}, all_models))

        for min_model in models:
            q_prime = frozenset({id2atom[s] for s in map(str, min_model)})
            new_macrostate.add(q_prime)

    return frozenset(new_macrostate)
Ejemplo n.º 17
0
from sympy import pprint, simplify, satisfiable
import equibel as eb

if __name__ == '__main__':
    formula = eb.random_formula(num_atoms=6, num_connectives=10)
    pprint(formula)

    for model in satisfiable(formula, all_models=True):
        print(model)

    simplified = simplify(formula)
    pprint(simplified)
Ejemplo n.º 18
0
# Build the solution to part A.
part_a_conjuncts = []
for pigeon in xrange(1, 5):
    term1 = And(P[pigeon][1], Not(P[pigeon][2]), Not(P[pigeon][3]))
    term2 = And(Not(P[pigeon][1]), (P[pigeon][2]), Not(P[pigeon][3]))
    term3 = And(Not(P[pigeon][1]), Not(P[pigeon][2]), (P[pigeon][3]))
    # Build the conjunction of the disjuncts.
    part_a_conjuncts.append(Or(term1, term2, term3))

# Build part A using conjuncts.
part_a = And(part_a_conjuncts[0], part_a_conjuncts[1],
             part_a_conjuncts[2], part_a_conjuncts[3])

print "PartA is satisfiable with the assignment:"
print str(satisfiable(part_a)) + "\n\n\n"

# Build part B.
part_b = False
for hole in xrange(1, 4):
    part_b = Or(part_b, And(P[1][hole], P[2][hole]))
    part_b = Or(part_b, And(P[1][hole], P[3][hole]))
    part_b = Or(part_b, And(P[1][hole], P[4][hole]))
    part_b = Or(part_b, And(P[2][hole], P[3][hole]))
    part_b = Or(part_b, And(P[2][hole], P[4][hole]))
    part_b = Or(part_b, And(P[3][hole], P[4][hole]))
print "PartB is satisfiable with the assignment:"
print str(satisfiable(part_b)) + "\n\n\n"

# Pigeon Hole Principle
php = And(part_a, part_b)
Ejemplo n.º 19
0
	rightSide = functools.reduce(lambda x,y:x^y, [False]+InitialWallaceWeights('n',n,'k',n,i,toAddToRightSide,rightSideLeftOvers)).subs(rightSideKnowns).subs(substitutes)
	rightSideLeftOvers = [rightSideTerm.subs(rightSideKnowns).subs(substitutes) for rightSideTerm in rightSideLeftOvers]
	# replacing n digits
	if shouldSubN:
	    rightSide = rightSide.subs(n_Subs)
	    rightSideLeftOvers = [rightSideTerm.subs(n_Subs) for rightSideTerm in rightSideLeftOvers]
	
	toAddToLeftSide = leftSideLeftOvers
	toAddToRightSide = rightSideLeftOvers
	
	equations.append((leftSide,rightSide))
	
	# adding new term to equalitis for new k
	newKkey = 'k{}'.format(len(equations)-1)
	if newKkey in D:
		substitutes[D[newKkey]] = equations[-1][0]^sympy.simplify_logic(equations[-1][1]^D[newKkey])
	else:
		satEquation = sympy.Equivalent(equations[-1][0],sympy.simplify_logic(equations[-1][1])) & satEquation
	print((bcolors.HEADER+"w:{:>2}"+bcolors.ENDC+" {:>"+str(math.floor(shutil.get_terminal_size((80,20))[0]/2)-2-3)+"}").format(i,sympy.pretty(equations[-1][0]))+bcolors.OKGREEN+" = "+bcolors.ENDC+sympy.pretty(equations[-1][1]))
	i += 1 

#print("number of terms in CNF for satisfiability: {}".format(len(to_cnf(satEquation.args))))

if shouldSubN & shouldSolve:
    print("=======Sat Equation=======")
    simplifiedSat = sympy.simplify_logic(satEquation)
    print(simplifiedSat)
    print("=Satisfiability solutions=")
    allModels = list(sympy.satisfiable(simplifiedSat,all_models=True))
    print(", ".join(map(str,[2*functools.reduce(lambda x,y:2*x+y, [0]+[int(model[D[x]]) for x in ["a{}".format(i+1) for i in reversed(range(n-1))]])+1 for model in allModels])))
Ejemplo n.º 20
0
def is_sat(formula, gt):
    return satisfiable(formula.subs(gt)) != False
Ejemplo n.º 21
0
# Tekijöihin jakoa:

# In[186]:


poly = x**4 - 3*x**2 + 1


# In[188]:


from sympy import factor
factor(poly)


# In[189]:


factor(poly,modulus=5)


# Boolean lausekkeita

# In[191]:


from sympy import satisfiable
satisfiable(x & y)

Ejemplo n.º 22
0
def solve_problem_no_teams(kb, kb_symbols, data_q, undefined, queries, num_of_observations, row_num, col_num, possible_states):
    answer = {}
    change = True
    police_num, medic_num= 0, 0
    kb_symbols = spreader(kb_symbols, undefined, kb, row_num, col_num, data_q, possible_states, police_num)
    while change:
        undefined_copy = undefined.copy()
        undefined_copy.reverse()
        for und in undefined_copy:
            isS = is_S(und, row_num, col_num, num_of_observations)
            kb_S = sympy.And(~isS, kb_symbols)
            kb_S_cnf = sympy.to_cnf(kb_S)
            res = sympy.satisfiable(kb_S_cnf)
            if not res:
                new_S = und + '_S'
                data_q.append(new_S)
                kb.append(new_S)
                undefined.remove(und)
                new_S = sympy.symbols(new_S)
                kb_symbols = sympy.And(kb_symbols, new_S)
                no_H = und + '_H'
                data_q.append('~' + no_H)
                no_H = sympy.symbols(no_H)
                kb_symbols = sympy.And(kb_symbols, ~no_H)
                no_U = und + '_U'
                if '~' + no_U not in data_q:
                    data_q.append('~' + no_U)
                    no_U = sympy.symbols(no_U)
                    kb_symbols = sympy.And(kb_symbols, ~no_U)
            else:
                isH = is_H(und, row_num, col_num, police_num, medic_num, num_of_observations)
                kb_H = sympy.And(~isH, kb_symbols)
                kb_H_cnf = sympy.to_cnf(kb_H)
                res = sympy.satisfiable(kb_H_cnf)
                if not res:
                    new_H = und + '_H'
                    data_q.append(new_H)
                    kb.append(new_H)
                    undefined.remove(und)
                    new_H = sympy.symbols(new_H)
                    kb_symbols = sympy.And(kb_symbols, new_H)
                    no_S = und + '_S'
                    data_q.append('~' + no_S)
                    no_S = sympy.symbols(no_S)
                    kb_symbols = sympy.And(kb_symbols, ~no_S)
                    no_U = und + '_U'
                    if '~' + no_U not in data_q:
                        data_q.append('~' + no_U)
                        no_U = sympy.symbols(no_U)
                        kb_symbols = sympy.And(kb_symbols, ~no_U)
        kb_symbols = spreader(kb_symbols, undefined, kb, row_num, col_num, data_q, possible_states, police_num)
        if set(undefined_copy) == set(undefined):
            change = False
    for quer in queries:
        place, number, s = quer
        i, j = place
        q = '{}_{}_{}_{}'.format(i, j, number, s)
        if q in data_q:
            answer[quer] = 'T'
        elif '~' + q in data_q:
            answer[quer] = 'F'
        else:
            answer[quer] = '?'
    return answer
Ejemplo n.º 23
0
 def solve(self, H):
     A,B,C,D = self.HtoABCD(H)
     eq = And(*[~(A[i] ^ self.a[i]) & ~(B[i] ^ self.b[i]) & ~(C[i] ^ self.c[i]) & ~(D[i] ^ self.d[i]) for i in range(32)])
     print("Equation:",eq)
     return satisfiable(eq)