Пример #1
0
 def _generate_solutions(cls, period, doms):
     """
     Each child gets as domain a set of ShiftAssignables, 
     which is generated by their shift preferences;
     each solution selects for each child a ShiftAssignable
     so that all assignments are compatible.
     Here we configure a problem from the constraint library,
     then call the solver.
     The problem takes a mapping, doms, from child_pk to a set of assignables for that child, plus a specification, across children, of which assignables are pairwise consistent
     The solver yields all compatible sets of assignables
     """
     problem = Problem()
     prefs = (ShiftPreference.objects.filter(
         period=period).select_related('shift').select_related('child'))
     for pref in prefs:
         for assignable in pref.assignables():
             if assignable.is_active:
                 doms[assignable.child.pk].append(assignable)
     for k, dom in doms.items():
         try:
             problem.addVariable(k, dom)
         except ValueError:
             return {}
     cached_compatibility = functools.lru_cache()(
         lambda a1, a2: a1.is_compatible_with(a2))
     for k1, k2 in itertools.combinations(doms.keys(), 2):
         problem.addConstraint(cached_compatibility, (k1, k2))
     # call the solver
     return problem.getSolutionIter()
Пример #2
0
def solution(dimension, solver=None):
    """Generate binary puzzle solution."""
    problem = Problem()
    if solver is not None:
        problem.setSolver(solver)
    else:
        problem.setSolver(BacktrackingSolver())
    problem.addVariables(range(dimension**2), [0, 1])
    for i in range(dimension):
        row_positions = range(i * dimension, (i + 1) * dimension)
        column_positions = range(i, dimension**2, dimension)
        # same number of zeros and ones in each row
        problem.addConstraint(ExactSumConstraint(dimension / 2), row_positions)
        problem.addConstraint(ExactSumConstraint(dimension / 2),
                              column_positions)
        # maximum two of the same next to each other
        for triplet in _nwise(row_positions, 3):
            problem.addConstraint(MaxSumConstraint(2), triplet)
            problem.addConstraint(MinSumConstraint(1), triplet)
        for triplet in _nwise(column_positions, 3):
            problem.addConstraint(MaxSumConstraint(2), triplet)
            problem.addConstraint(MinSumConstraint(1), triplet)
    # unique rows and columns
    problem.addConstraint(
        FunctionConstraint(partial(_test_uniqueness, dimension=dimension)),
        range(dimension**2))
    if isinstance(solver, RecursiveBacktrackingSolver):
        return problem.getSolutions()
    if isinstance(solver, MinConflictsSolver):
        return (problem.getSolution(), )
    return problem.getSolutionIter()
Пример #3
0
    def generateSchedule(self, assignments, scoring_function):
        """ Generate schedule for a user based on scoring_function and user's existing schedule
        """
        problem = Problem()
        solution = {}
        print("Name: {self.name}")
        print("Existing schedule: {self.schedule}")
        print(
            f"Possible Rotations: {self.possibleRotations}\nOrder: {self.order}"
        )
        print()
        if len(self.possibleRotations) > 0:
            problem.addVariables(self.possibleRotations, self.order)

            # HARD CONSTRAINT 1 - All rotations must be unique in the period of the program
            problem.addConstraint(AllDifferentConstraint(),
                                  self.possibleRotations)
            solutions = problem.getSolutions()

            # Score the options
            print(f"Scoring {len(solutions)} found")
            scores = np.zeros(len(solutions))
            for sidx, solution in enumerate(solutions):
                scores[sidx] = scoring_function(
                    assignments, sorted(solution.items(), key=lambda x: x[1]),
                    self.earliestAvailableDate())

            chosen = np.argsort(scores)
            solution = solutions[chosen[0]]
            print(f"Best solution: {solution}")
        return solution
Пример #4
0
    def _cp_step(self, state, prob):
        """ The constraint programming step.

            This is one of the more complicated steps; it divides the boundary into
            components that don't influence each other first, then divides each of those into areas that are equally
            constrained and must therefore have the same probabilities. The combinations of the number of mines in those
            components is computed with constraint programming. Those solutions are then combined to count the number of
            models in which each area has the given number of mines, from which we can calculate the average expected
            number of mines per square in a component if it has M mines, i.e. per component we have a mapping of
            {num_mines: (num_models, avg_prob)}. This information is then passed on to the combining step to form the
            final probabilities.

            :param state: The reduced state.
            :param prob: The already computed probabilities.
            :returns: The exact probability for every unknown square.
        """
        components, num_components = self._components(state)
        c_counts = []   # List of model_count_by_m instances from inside the 'for c' loop.
        c_probs = []    # List of model_count_by_m instances from inside the 'for c' loop.
        m_known = self.known_mine_count()
        # Solve each component individually
        for c in range(1, num_components+1):
            areas, constraints = self._get_areas(state, components == c)
            # Create a CP problem to determine which combination of mines per area is possible.
            problem = Problem()
            # Add all variables, each one having a domain [0, num_squares].
            for v in areas.values():
                problem.addVariable(v, range(len(v)+1))
            # Now constrain how many mines areas can have combined.
            for constraint in constraints:
                problem.addConstraint(constraint, [v for k, v in areas.items() if constraint in k])
            # Add a constraint so that the maximum number of mines never exceeds the number of mines left.
            problem.addConstraint(MaxSumConstraint(self._total_mines - m_known), list(areas.values()))
            solutions = problem.getSolutions()
            model_count_by_m = {}       # {m: #models}
            model_prob_by_m = {}        # {m: prob of the average component model}
            # Now count the number of models that exist for each number of mines in that component.
            for solution in solutions:
                m = sum(solution.values())
                # Number of models that match this solution.
                model_count = self._count_models(solution)
                # Increase counter for the number of models that have m mines.
                model_count_by_m[m] = model_count_by_m.get(m, 0) + model_count
                # Calculate the probability of each square in the component having a mines.
                model_prob = np.zeros(prob.shape)
                for area, m_area in solution.items():
                    # The area has `m_area` mines in it, evenly distributed.
                    model_prob[tuple(zip(*area))] = m_area/len(area)
                # Sum up all the models, giving the expected number of mines of all models combined
                model_prob_by_m[m] = model_prob_by_m.get(m, np.zeros(prob.shape)) + model_count*model_prob
            # We've summed the probabilities of each solution, weighted by the number of models with those
            # probabilities, now divide out the total number of models to obtain the probability of each square of a
            # model with m mines having a mine.
            model_prob_by_m = {m: model_prob/model_count_by_m[m] for m, model_prob in model_prob_by_m.items()}
            c_probs.append(model_prob_by_m)
            c_counts.append(model_count_by_m)
        prob = self._combine_components(state, prob, c_probs, c_counts)
        return prob
Пример #5
0
    def run(self, dag):
        """run the layout method"""
        qubits = dag.qubits
        cxs = set()

        from constraint import Problem, AllDifferentConstraint, RecursiveBacktrackingSolver
        from qiskit.transpiler.passes.layout._csp_custom_solver import CustomSolver

        for gate in dag.two_qubit_ops():
            cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1])))
        edges = set(self.coupling_map.get_edges())

        if self.time_limit is None and self.call_limit is None:
            solver = RecursiveBacktrackingSolver()
        else:
            solver = CustomSolver(call_limit=self.call_limit,
                                  time_limit=self.time_limit)

        variables = list(range(len(qubits)))
        variable_domains = list(self.coupling_map.physical_qubits)
        random.Random(self.seed).shuffle(variable_domains)

        problem = Problem(solver)
        problem.addVariables(variables, variable_domains)
        problem.addConstraint(
            AllDifferentConstraint())  # each wire is map to a single qubit

        if self.strict_direction:

            def constraint(control, target):
                return (control, target) in edges

        else:

            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        solution = problem.getSolution()

        if solution is None:
            stop_reason = "nonexistent solution"
            if isinstance(solver, CustomSolver):
                if solver.time_current is not None and solver.time_current >= self.time_limit:
                    stop_reason = "time limit reached"
                elif solver.call_current is not None and solver.call_current >= self.call_limit:
                    stop_reason = "call limit reached"
        else:
            stop_reason = "solution found"
            self.property_set["layout"] = Layout(
                {v: qubits[k]
                 for k, v in solution.items()})
            for reg in dag.qregs.values():
                self.property_set["layout"].add_register(reg)

        self.property_set["CSPLayout_stop_reason"] = stop_reason
def solver(domain, appointments):
    problem = Problem()
    ConstraintGraphCost = nx.Graph()
    variablesName = []
    # for each appointment (iterate on the numerical key of the appointments)
    for x in appointments:
        dom = []
        # check which elements of the generic domain are necessary for this appointment
        for y in domain:
            hour, minutes = y[1].split(".")
            hour = int(hour)
            #print(appointments[x])
            #print(appointments[x]["Day"])

            for a in appointments[x]["Day"]:
                if "Morning" == a[1] and hour < 12 and y[0] in a[0] and y[
                        2] in appointments[x]["House"]:
                    dom.append(y)

                if "Afternoon" == a[1] and hour > 12 and y[0] in a[0] and y[
                        2] in appointments[x]["House"]:
                    dom.append(y)

        #Aggiungo la variabile corrente con il domain aggiustato
    #    print(dom)
        variablesName.append(x)
        ConstraintGraphCost.add_node(x, domain=dom)
        problem.addVariable(x, dom)

    a = itertools.combinations(variablesName, 2)

    for i in a:
        #print("Considero ", i)
        stop = False
        for domItem1 in ConstraintGraphCost.nodes[i[0]]['domain']:
            if (stop):
                break
            else:
                for domItem2 in ConstraintGraphCost.nodes[i[1]]['domain']:
                    if domItem1[0] == domItem2[0] and domItem1[1] == domItem2[
                            1] and domItem1 != "notScheduled":
                        #print("creo edge")
                        ConstraintGraphCost.add_edge(i[0], i[1])
                        problem.addConstraint(constraintFunction(),
                                              (i[0], i[1]))
                        stop = True
                        break

    start = current_milli_time()
    solution = problem.getSolution()
    end = current_milli_time()
    print("\n\n###########Time spent to find the first solution = ",
          end - start, " ms.\n\n")

    # pp.pprint(solution)

    return solution
Пример #7
0
def test_toy_python_constraint():
    def func1(a):
        return a < 0

    p = Problem()
    p.addVariable("a", [-1, -2, 0, 1, 2])
    p.addConstraint(func1, ["a"])
    result = p.getSolutions()
    print(result)
Пример #8
0
def solve_board(overlays, verify_just_one=False):
    problem = Problem()
    spot_constraints = defaultdict(list)
    overlay_constraints = []
    for overlay in overlays:
        # the simplest case is a fully 3x3 grid
        if len(overlay) == 3 and len(overlay[0]) == 3:
            for x in range(3):
                for y in range(3):
                    if overlay[x][y] is None:
                        continue
                    spot_constraints[(x, y)].extend(
                        get_constraints(overlay[x][y]))
        else:
            # dealing with a grid that is smaller than 3x3 so we
            # need to make relative constraints - we add those
            # after the all different constraint so it only needs
            # to look at possible boards
            overlay_constraints.append(
                (FunctionConstraint(floating_overlay(overlay)),
                 locations))

    # the unspecified spots could be any piece
    for x in range(3):
        for y in range(3):
                if (x, y) not in spot_constraints:
                    spot_constraints[(x, y)] = pieces

    for spot, values in spot_constraints.iteritems():
        problem.addVariable(spot, values)

    problem.addConstraint(AllDifferentConstraint())

    for overlay_constraint in overlay_constraints:
        problem.addConstraint(*overlay_constraint)

    solution = None

    if verify_just_one:
        solutions = problem.getSolutions()
        assert len(solutions) == 1, ('%d solutions but there should be 1' %
                                     len(solutions))
        solution = solutions[0]
    else:
        solution = problem.getSolution()

    answer = [[None] * 3 for x in range(3)]
    for x in range(3):
        for y in range(3):
            answer[x][y] = solution[(x, y)]

    print('\n'.join(' '.join(_) for _ in answer))
    print('')

    return answer
Пример #9
0
def solve():
    problem = Problem()
    total = 3.00
    variables = ("0.02", "0.09", "0.13", "1.50", "2.00")
    values = [float(x) for x in variables]
    for variable, value in zip(variables, values):
        problem.addVariable(variable, range(int(total / value)))
    problem.addConstraint(ExactSumConstraint(total, values), variables)
    problem.addConstraint(ExactSumConstraint(100))
    solutions = problem.getSolutionIter()
    return solutions, variables
Пример #10
0
def solve():
    problem = Problem()
    total = 5.00
    variables = ("0.01", "0.05", "0.10", "0.50", "1.00")
    values = [float(x) for x in variables]
    for variable, value in zip(variables, values):
        problem.addVariable(variable, range(int(total / value)))
    problem.addConstraint(ExactSumConstraint(total, values), variables)
    problem.addConstraint(ExactSumConstraint(100))
    solutions = problem.getSolutionIter()
    return solutions, variables
def test_constraint():
    c = Problem()
    c.addVariable("i", range(-100, 10))
    c.addVariable("j", range(-10, 10))
    c.addVariable("k", range(-10, 10))
    c.addConstraint(lambda i, j, k: i <= 0 or j <= 0 or k <= 0, ("i", "j", "k"))
    C = CustomConstraint(c)
    values1 = [-1, -1, -1]
    values2 = [9, 8, 2]
    assert C.to_fitness(values1) == 9963.0
    assert C.to_fitness(values2) == 12349.0
Пример #12
0
def solve(size):
    problem = Problem()
    cols = range(size)
    rows = range(size)
    problem.addVariables(cols, rows)
    for col1 in cols:
        for col2 in cols:
            if col1 < col2:
                problem.addConstraint(lambda row1, row2: row1 != row2,
                                      (col1, col2))
    solutions = problem.getSolutions()
    return solutions
Пример #13
0
def solve():
    problem = Problem()
    problem.addVariables("twofur", range(10))
    problem.addConstraint(lambda o, r: (2 * o) % 10 == r, "or")
    problem.addConstraint(lambda w, o, u,
                          r: ((10 * 2 * w) + (2 * o)) % 100 == u * 10 + r, "wour")
    problem.addConstraint(lambda t, w, o, f, u, r:
                          2 * (t * 100 + w * 10 + o) ==
                          f * 1000 + o * 100 + u * 10 + r, "twofur")
    problem.addConstraint(NotInSetConstraint([0]), "ft")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #14
0
def color(map, colors=['red', 'green', 'blue']):
    (vars, adjoins) = parse_map(map)
    p = Problem()
    p.addVariables(vars, colors)
    for (v1, v2) in adjoins:
        p.addConstraint(NEQ, [v1, v2])
    solution = p.getSolution()
    if solution:
        for v in sorted(vars):
            print("{}:{} ".format(v, solution[v]), end='')
        print()
    else:
        print('No solution found :-(')
Пример #15
0
def processResults(all_data):

    prob = Problem()
    for i, d in enumerate(all_data):
        prob.addVariable(i, d["logic"])

    prob.addConstraint(MaxSumConstraint(234720))

    solutions = prob.getSolutionIter()

    for i, s in enumerate(solutions):
        if i % 1000 == 0:
            print(i)
Пример #16
0
def solve():
    problem = Problem()
    problem.addVariables("twofur", range(10))
    problem.addConstraint(lambda o, r: (2 * o) % 10 == r, "or")
    problem.addConstraint(lambda w, o, u,
                          r: ((10 * 2 * w) + (2 * o)) % 100 == u * 10 + r, "wour")
    problem.addConstraint(lambda t, w, o, f, u, r:
                          2 * (t * 100 + w * 10 + o) ==
                          f * 1000 + o * 100 + u * 10 + r, "twofur")
    problem.addConstraint(NotInSetConstraint([0]), "ft")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #17
0
def buildproblem(terms, total):
    problem = Problem()

    letters = sorted(list(set("".join(terms) + total)))
    initial = set([word[0] for word in terms + [total]])

    for letter in letters:
        if letter in initial:
            problem.addVariable(letter, list(range(1,10)))
        else:
            problem.addVariable(letter, list(range(10)))
    problem.addConstraint(AllDifferentConstraint())
    digit_checks(problem, terms, total, letters)
    return problem
Пример #18
0
def buildproblem(terms, total):
    problem = Problem()

    letters = sorted(list(set("".join(terms) + total)))
    initial = set([word[0] for word in terms + [total]])

    for letter in letters:
        if letter in initial:
            problem.addVariable(letter, list(range(1, 10)))
        else:
            problem.addVariable(letter, list(range(10)))
    problem.addConstraint(AllDifferentConstraint())
    digit_checks(problem, terms, total, letters)
    return problem
Пример #19
0
def solve():
    problem = Problem()
    size = 8
    cols = range(size)
    rows = range(size)
    problem.addVariables(cols, rows)
    for col1 in cols:
        for col2 in cols:
            if col1 < col2:
                problem.addConstraint(lambda row1, row2, col1=col1, col2=col2:
                                      abs(row1 - row2) != abs(col1 - col2) and
                                      row1 != row2, (col1, col2))
    solutions = problem.getSolutions()
    return solutions, size
def solve():
    problem = Problem()
    problem.addVariables("seidoz", range(10))
    problem.addConstraint(lambda s, e: (2 * s) % 10 == e, "se")
    problem.addConstraint(lambda i, s, z, e: ((10 * 2 * i) + (2 * s)) % 100 ==
                          z * 10 + e, "isze")
    problem.addConstraint(lambda s, e, i, d, o, z:
                          2 * (s * 1000 + e * 100 + i * 10 + s) ==
                          d * 1000 + o * 100 + z * 10 + e, "seidoz")
    problem.addConstraint(lambda s: s != 0, "s")
    problem.addConstraint(lambda d: d != 0, "d")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #21
0
    def run(self, dag):
        qubits = dag.qubits
        cxs = set()

        for gate in dag.two_qubit_ops():
            cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1])))
        edges = set(self.coupling_map.get_edges())

        if self.time_limit is None and self.call_limit is None:
            solver = RecursiveBacktrackingSolver()
        else:
            solver = CustomSolver(call_limit=self.call_limit,
                                  time_limit=self.time_limit)

        problem = Problem(solver)
        problem.addVariables(list(range(len(qubits))),
                             self.coupling_map.physical_qubits)
        problem.addConstraint(
            AllDifferentConstraint())  # each wire is map to a single qubit

        if self.strict_direction:

            def constraint(control, target):
                return (control, target) in edges
        else:

            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        random.seed(self.seed)
        solution = problem.getSolution()

        if solution is None:
            stop_reason = 'nonexistent solution'
            if isinstance(solver, CustomSolver):
                if solver.time_current is not None and solver.time_current >= self.time_limit:
                    stop_reason = 'time limit reached'
                elif solver.call_current is not None and solver.call_current >= self.call_limit:
                    stop_reason = 'call limit reached'
        else:
            stop_reason = 'solution found'
            self.property_set['layout'] = Layout(
                {v: qubits[k]
                 for k, v in solution.items()})

        self.property_set['CSPLayout_stop_reason'] = stop_reason
Пример #22
0
def team_solver(all_players, max_overall):

    problem = Problem()
    for position in all_players:
        problem.addVariable(position, all_players[position])

    def constraint(pg, sg, sf, pf, c):
        team_overall = pg['player']['overall'] + sg['player']['overall'] + \
                       sf['player']['overall'] + pf['player']['overall'] + \
                       c['player']['overall']
        return team_overall <= max_overall

    problem.addConstraint(constraint)

    return problem.getSolutions()
Пример #23
0
def test_least_conflicts_solver():
    # another test for LeastConflictsSolver

    problem = Problem(LeastConflictsSolver())

    result = [[('a', 1), ('b', 2), ('c', 1)], [('a', 2), ('b', 1), ('c', 1)],
              [('a', 2), ('b', 2), ('c', 1)]]

    problem.addVariables(["a", "b"], [1, 2])
    problem.addVariable("c", [1])
    problem.addConstraint(lambda a, b: b != a, ["a", "b"])
    problem.addConstraint(lambda a, b: b != a, ["a", "c"])
    problem.addConstraint(lambda a, b: b != a, ["b", "c"])

    solution = problem.getSolution()
    assert sorted(solution.items()) in result
Пример #24
0
def solve():
    problem = Problem()
    problem.addVariables("seidoz", range(10))
    problem.addConstraint(lambda s, e: (2 * s) % 10 == e, "se")
    problem.addConstraint(
        lambda i, s, z, e: ((10 * 2 * i) + (2 * s)) % 100 == z * 10 + e,
        "isze")
    problem.addConstraint(
        lambda s, e, i, d, o, z: 2 *
        (s * 1000 + e * 100 + i * 10 + s) == d * 1000 + o * 100 + z * 10 + e,
        "seidoz")
    problem.addConstraint(lambda s: s != 0, "s")
    problem.addConstraint(lambda d: d != 0, "d")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #25
0
    def get_solution(genome_index: pd.Index, genome_constraints: pd.DataFrame,
                     i: int) -> dict:
        solutions = {}
        final_solution = {}

        while solutions is not None:

            problem = Problem(MinConflictsSolver())
            problem.addVariables(list(genome_index), range(1, i))

            unmatched_regions = genome_constraints[
                genome_constraints.constraint == 0]
            # todo extract to method
            unmatched_regions.apply(lambda row: problem.addConstraint(
                lambda row1, row2: row1 != row2,
                (row['index_x'], row['index_y'])),
                                    axis=1)

            print("generating a solution for", i - 1, "groups")
            solutions = problem.getSolution()

            if solutions is not None:
                print("solution found for", i - 1, "groups")
                i -= 1
                final_solution = solutions
            else:
                print("no solution for", i - 1,
                      "groups, therefore optimal solution is", i, "groups")
        return final_solution
Пример #26
0
def derive_depths(marker_list, additional_constraints=[]):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if not marker_list:
        return []
    problem = Problem()

    # Marker type per marker
    problem.addVariables(["type" + str(i) for i in range(len(marker_list))],
                         markers.types)
    # Index within the marker list
    problem.addVariables(["idx" + str(i) for i in range(len(marker_list))],
                         range(51))
    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))
    all_vars = []
    for i in range(len(marker_list)):
        all_vars.extend(['type' + str(i), 'idx' + str(i), 'depth' + str(i)])

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0", ))

    for idx, marker in enumerate(marker_list):
        idx_str = str(idx)
        problem.addConstraint(rules.type_match(marker),
                              ("type" + idx_str, "idx" + idx_str))

        prior_params = ['type' + idx_str, 'idx' + idx_str, 'depth' + idx_str]
        for i in range(idx):
            prior_params += ['type' + str(i), 'idx' + str(i), 'depth' + str(i)]

        problem.addConstraint(rules.same_type, prior_params)
        problem.addConstraint(rules.diff_type, prior_params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_depth_same_type, all_vars)
    problem.addConstraint(rules.stars_occupy_space, all_vars)

    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    return [Solution(solution) for solution in problem.getSolutions()]
Пример #27
0
def derive_depths(marker_list, additional_constraints=[]):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if not marker_list:
        return []
    problem = Problem()

    # Marker type per marker
    problem.addVariables(["type" + str(i) for i in range(len(marker_list))],
                         markers.types)
    # Index within the marker list
    problem.addVariables(["idx" + str(i) for i in range(len(marker_list))],
                         range(51))
    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))
    all_vars = []
    for i in range(len(marker_list)):
        all_vars.extend(['type' + str(i), 'idx' + str(i), 'depth' + str(i)])

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0",))

    for idx, marker in enumerate(marker_list):
        idx_str = str(idx)
        problem.addConstraint(rules.type_match(marker),
                              ("type" + idx_str, "idx" + idx_str))

        prior_params = ['type' + idx_str, 'idx' + idx_str, 'depth' + idx_str]
        for i in range(idx):
            prior_params += ['type' + str(i), 'idx' + str(i), 'depth' + str(i)]

        problem.addConstraint(rules.same_type, prior_params)
        problem.addConstraint(rules.diff_type, prior_params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_depth_same_type, all_vars)
    problem.addConstraint(rules.stars_occupy_space, all_vars)

    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    return [Solution(solution) for solution in problem.getSolutions()]
Пример #28
0
def solver(domain, appointments):
    problem = Problem()

    # for each appointment (iterate on the numerical key of the appointments)
    for x in appointments:
        dom = []

        # check which elements of the generic domain are necessary for this appointment
        for y in domain:
            hour, minutes = y[1].split(".")
            hour = int(hour)

            if "Morning" in appointments[x]["Pref"] and hour < 12 and y[
                    0] in appointments[x]["Day"] and y[2] in appointments[x][
                        "House"]:
                dom.append(y)

            if "Afternoon" in appointments[x]["Pref"] and hour > 12 and y[
                    0] in appointments[x]["Day"] and y[2] in appointments[x][
                        "House"]:
                dom.append(y)

        # print("FOR APPOINTMENT:\n")
        # pp.pprint(x)
        # print("The domain is:\n")
        # pp.pprint(dom)

        # add a variable to the CSP problem with the appointment *x* and the just computed domain *dom*
        problem.addVariable(x, dom)

    # add constraints
    for x in appointments:
        for y in appointments:
            if (x != y):
                problem.addConstraint(constraintFunction(), (x, y))

    start = current_milli_time()
    solution = problem.getSolution()
    end = current_milli_time()
    print("\n\n###########Time spent to find the first solution = ",
          end - start, " ms.\n\n")

    # pp.pprint(solution)

    return solution
Пример #29
0
def solve_puzzles(puzzles, solver):
    """
    Solves an array of sudoku puzzles, recording runtime.

    :param puzzles: an array of 2D array boards
    :param solver: the CSP solver to be used
    :return: none
    """
    fail_count = 0
    start_time = datetime.now()     # start timer (for runtime)

    for puzzle in puzzles:
        # initialize Board
        b = Board(puzzle)

        sudoku = Problem(solver)      # initialize CSP with custom solver

        # add variables for each square, indexed 1...size^2
        for index in range(b.board_size ** 2):
            value = b.get_value(index)

            if value == 0:
                sudoku.addVariable(index, range(1, b.board_size + 1))
            else:
                sudoku.addVariable(index, [value])

        # add uniqueness constraints to each row, column, and subsquare
        for i in range(b.board_size):
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.row(i)])
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.col(i)])
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.subsquare(i)])

        sln = sudoku.getSolution()      # solve CSP

        if sln:
            # assign solved values
            for index, value in sln.items():
                b.set_value(index, value)
        else:
            fail_count += 1

    # perform/display runtime calculation
    runtime = datetime.now() - start_time
    print("Runtime: {} seconds ({} failed)".format(runtime.total_seconds(), fail_count))
Пример #30
0
def compute_using_external_solver(predicate, env, varList):
    # TODO: import at module level
    # external software:
    # install http://labix.org/python-constraint
    # download and unzip python-constraint-1.1.tar.bz2
    # python setup.py build
    # python setup.py install
    #from pretty_printer import pretty_print
    #print "predicate:", pretty_print(predicate)
    from constraint import Problem
    assert isinstance(predicate, Predicate)
    var_and_domain_lst = []
    # get domain 
    for idNode in varList:
        assert isinstance(idNode, AIdentifierExpression)
        atype = env.get_type_by_node(idNode)
        #if USE_RPYTHON_CODE:
        #    domain = all_values_by_type_RPYTHON(atype, env, idNode)
        #else:
        #    domain = all_values_by_type(atype, env, idNode)
        domain = all_values_by_type(atype, env, idNode)
        tup = (idNode.idName, domain)
        var_and_domain_lst.append(tup)
    problem = Problem() # import from "constraint"
    for tup in var_and_domain_lst:
        name = tup[0]
        lst  = tup[1]
        if isinstance(lst, frozenset):
            lst = set_to_list(lst) 
        problem.addVariable(name, lst)
    qme_nodes = []
    constraint_string = pretty_print_python_style(env, varList, predicate, qme_nodes)
    names = [x.idName for x in varList]
    expr = "lambda "
    for n in names[0:-1]:
        expr += n+","
    expr += varList[-1].idName+":"+constraint_string
    #print expr
    my_globales = {"qme_nodes":qme_nodes, "quick_member_eval":quick_member_eval, "env":env}
    lambda_func = eval(expr, my_globales)  # TODO:(#ISSUE 16) not Rpython
    problem.addConstraint(lambda_func, names)
    return problem.getSolutionIter()
Пример #31
0
        def try_assignment():
            problem = Problem()

            for variable in self.variables:
                candidates = [assignment[variable.name]] if variable.name in assignment else groups
                domain = list([g for g in candidates if any(st in variable.types for st in
                                                            (Typing.as_legacy_type(gt) for gt in g.vector_types))])
                if len(domain) == 0:
                    return variable.name in assignment, []
                problem.addVariable(variable.name, domain)

            for f in filters:
                variables = list([v.name for v in f.variables])

                def c_j(ff, vv):
                    return lambda *args: ff.test_relaxed({vv[i]: args[i] for i in range(len(args))}, solutions)

                problem.addConstraint(c_j(f, variables), variables)

            return True, list(problem.getSolutions())
Пример #32
0
def solve(ac=False, pc=False):
    problem = Problem()
    # Countries
    countries = ['A', 'B', 'C']
    # Number of colors
    num_colors = 2
    # Neighbours on the map
    neighbours = ['AB', 'BC', 'CA']

    neighbours = [''.join(sorted(n)) for n in neighbours]
    problem.addVariables(countries, range(num_colors))
    for country1 in countries:
        for country2 in countries:
            if country1 != country2:
                constraint = lambda color1, color2, country1=country1, country2=country2: not any(
                    ''.join(sorted(country1 + country2)) in s
                    for s in neighbours) or color1 != color2
                problem.addConstraint(constraint, [country1, country2])
    solutions = problem.getSolutions(ac, pc)
    print('Solutions:\n', solutions)
    return solutions
Пример #33
0
def player_solver(players, attribute_bounds):
    def create_constraint(attribute, bounds):
        min_value, max_value = bounds

        def constraint(player):
            return min_value <= player[attribute]

        return constraint

        # def constraint(player):
        #     return min_value <= player[attribute] <= max_value
        # return constraint

    problem = Problem()
    problem.addVariable("player", players)

    for attribute, bounds in attribute_bounds.items():
        constraint = create_constraint(attribute, bounds)
        problem.addConstraint(constraint, ["player"])

    return problem.getSolutions()
Пример #34
0
def test_addVariable_support_domain_subclasses():
    class MyCustomDomain(Domain):
        pass

    class MyConstraint(Constraint):
        def __call__(self,
                     variables,
                     domains,
                     assignments,
                     forwardcheck=False):
            assert isinstance(domains['x'], Domain)
            assert isinstance(domains['y'], MyCustomDomain)
            return True

    problem = Problem()
    problem.addVariable("x", [0, 1])
    problem.addVariable("y", MyCustomDomain([0, 1]))
    problem.addConstraint(MyConstraint())
    solution = problem.getSolution()

    possible_solutions = [
        {
            "x": 0,
            "y": 0
        },
        {
            "x": 0,
            "y": 1
        },
        {
            "x": 1,
            "y": 0
        },
        {
            "x": 1,
            "y": 1
        },
    ]

    assert solution in possible_solutions
Пример #35
0
def solve():
    problem = Problem()

    size = matrixOfStrimko.size + 1

    # Define the variables:  rows of x variables rangin in 1...x
    # x = tam of the matrix
    for i in range(1, size):
        problem.addVariables(range(i * 10 + 1, i * 10 + size), range(1, size))

    #Each row has different values
    for i in range(1, size):
        problem.addConstraint(AllDifferentConstraint(),
                              range(i * 10 + 1, i * 10 + size))

    # Each colum has different values
    for i in range(1, size):
        problem.addConstraint(AllDifferentConstraint(),
                              range(10 + i, 10 * size + i, 10))

    #Each route has different values
    for i in range(0, size - 1):
        problem.addConstraint(AllDifferentConstraint(),
                              matrixOfStrimko.routes[i].elements)

    return problem.getSolutions()
Пример #36
0
	def computeChannels(self, n, k=2):
		from constraint import Problem
		from constraint import SomeInSetConstraint
		found = False
		nodes = tuple(self.nodes())
		p = Problem()
		p.addVariables(list(self.nodes()), range(n,0,-1)) # reverse ordering the domain biases the constraint solver towards smaller numbers
		p.addConstraint(SomeInSetConstraint([1]))
		def addConstraint(node1, node2, dist, diff):
			if(node1 in node2.neighbors(dist)):
				p.addConstraint(lambda x, y: abs(x - y) >= diff,(node1, node2))
				return True
			return False

		for i in xrange(len(nodes)-1):
			n1 = nodes[i]
			for j in xrange(i+1,len(nodes)):
				n2 = nodes[j]
				if(not addConstraint(n1, n2, 2, k)): # each node pair needs no more than 1 constraint
					addConstraint(n1, n2, 4, 1)
		for rowIter in self.rows():
			row = tuple(rowIter)
			for i in xrange(len(row)-1):
				p.addConstraint(lambda x, y: y == (x + k) % n + 1,(row[i], row[i+1]))
		for colIter in self.columns():
			col = tuple(colIter)
			for i in xrange(len(col)-1):
				p.addConstraint(lambda x, y: y == (x + k - 1) % n + 1,(col[i], col[i+1]))
		solution = p.getSolution()
		if(solution == None):
			return found
		found = True
		for node,channel in p.getSolution().iteritems():
			node.channel = channel
		return True
Пример #37
0
    def determine(state):
        card_played_this_round = [
            card is not None and 1 or 0
            for card in state.cards_played_by_player
        ]
        remaining_hand_size = 5 - sum(state.tricks_won_by_team)
        hand_size_by_player = [
            remaining_hand_size - played for played in card_played_this_round
        ]
        cards = list(
            set(deal()) - set(list(chain(*state.hands))) -
            set(state.cards_played))
        shuffle(cards)

        problem = Problem()
        for player in range(4):
            if state.hands[player]:
                for card_index, card in enumerate(state.hands[player]):
                    problem.addVariable((player, card_index), [card])
            else:
                voids_by_player = state.voids_by_player[player]
                for card_index in range(hand_size_by_player[player]):
                    if voids_by_player:
                        potential_cards = potential_cards_given_voids(
                            state.trump, voids_by_player, cards)
                        shuffle(potential_cards)
                        problem.addVariable((player, card_index),
                                            potential_cards)
                    else:
                        problem.addVariable((player, card_index), cards)
        problem.addConstraint(AllDifferentConstraint())

        cards = sorted(iteritems(problem.getSolution()))
        hands = [[], [], [], []]
        for player in range(4):
            hands[player] = [c[1] for c in cards[:hand_size_by_player[player]]]
            del cards[:hand_size_by_player[player]]

        state = state._replace(hands=hands)
        return state
Пример #38
0
def kakuroCSP():

  # Pre: variables and equations have been computed by sanityCheck
  # Will be run in a background thread

  global solutions, variables       # will be accessed by main thread
  global solverDone

  problem = Problem()

  # Restrict the value of each white square as much as possible

  domains = defaultdict(set)
  univ = list(range(1,10))
  for n in univ:
    for c in combinations(univ, n):
      domains[sum(c), n] |= set(c)

  candidates = {v: set(univ) for v in variables}
  for eq in equations:
    for v in eq.variables:
      candidates[v] &= domains[eq.clue, len(eq.variables)]

  # one variable for each white square, with values in range computed above

  for v in variables:
    problem.addVariable(v, tuple(candidates[v]))

  for eq in equations:
    # All the numbers in a single sum are distinct

    problem.addConstraint(AllDifferentConstraint(), eq.variables)

    # The numbers must sum to the clue

    problem.addConstraint(ExactSumConstraint(eq.clue), eq.variables)

  solutions = problem.getSolutions()
  solverDone = True
Пример #39
0
    def determine(state):
        card_played_this_round = [card is not None and 1 or 0
                                  for card in state.cards_played_by_player]
        remaining_hand_size = 5 - sum(state.tricks_won_by_team)
        hand_size_by_player = [remaining_hand_size - played
                               for played in card_played_this_round]
        cards = list(set(deal()) -
                     set(list(chain(*state.hands))) -
                     set(state.cards_played))
        shuffle(cards)

        problem = Problem()
        for player in range(4):
            if state.hands[player]:
                for card_index, card in enumerate(state.hands[player]):
                    problem.addVariable((player, card_index),
                                        [card])
            else:
                voids_by_player = state.voids_by_player[player]
                for card_index in range(hand_size_by_player[player]):
                    if voids_by_player:
                        potential_cards = potential_cards_given_voids(
                            state.trump, voids_by_player, cards)
                        shuffle(potential_cards)
                        problem.addVariable((player, card_index),
                                            potential_cards)
                    else:
                        problem.addVariable((player, card_index), cards)
        problem.addConstraint(AllDifferentConstraint())

        cards = sorted(iteritems(problem.getSolution()))
        hands = [[], [], [], []]
        for player in range(4):
            hands[player] = [c[1] for c in cards[:hand_size_by_player[player]]]
            del cards[:hand_size_by_player[player]]

        state = state._replace(hands=hands)
        return state
def solve():
    problem = Problem()
    problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"])
    problem.addConstraint(SomeInSetConstraint(["A"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["B"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["C"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["D"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["E"], 4, True))
    for row in range(len(STUDENTDESKS) - 1):
        for col in range(len(STUDENTDESKS[row]) - 1):
            lst = [STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1],
                   STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1]]
            lst = [x for x in lst if x]
            problem.addConstraint(AllDifferentConstraint(), lst)
    solutions = problem.getSolution()
    return solutions
Пример #41
0
    def run(self, dag):
        try:
            from constraint import Problem, RecursiveBacktrackingSolver, AllDifferentConstraint
        except ImportError:
            raise TranspilerError('CSPLayout requires python-constraint to run. '
                                  'Run pip install python-constraint')
        qubits = dag.qubits()
        cxs = set()

        for gate in dag.twoQ_gates():
            cxs.add((qubits.index(gate.qargs[0]),
                     qubits.index(gate.qargs[1])))
        edges = self.coupling_map.get_edges()

        problem = Problem(RecursiveBacktrackingSolver())

        problem.addVariables(list(range(len(qubits))), self.coupling_map.physical_qubits)

        problem.addConstraint(AllDifferentConstraint())  # each wire is map to a single qbit

        if self.strict_direction:
            def constraint(control, target):
                return (control, target) in edges
        else:
            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        random.seed(self.seed)
        solution = problem.getSolution()

        if solution is None:
            return

        self.property_set['layout'] = Layout({v: qubits[k] for k, v in solution.items()})
Пример #42
0
def solve():
    problem = Problem()
    problem.addVariables("abcdxefgh", range(1, 10))
    problem.addConstraint(lambda a, b, c, d, x:
                          a < b < c < d and a + b + c + d + x == 27, "abcdx")
    problem.addConstraint(lambda e, f, g, h, x:
                          e < f < g < h and e + f + g + h + x == 27, "efghx")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #43
0
class SudokuProblem(object):
    def __init__(self):
        self._problem = Problem()

    def _each_once_per_line(self):
        for line_index in range(9):
            variable_names = [self._variable_name(line_index, column_index) for column_index in range(9)]
            self._problem.addConstraint(AllDifferentConstraint(), variable_names)

    def _each_once_per_column(self):
        for column_index in range(9):
            variable_names = [self._variable_name(line_index, column_index) for line_index in range(9)]
            self._problem.addConstraint(AllDifferentConstraint(), variable_names)

    def _each_once_per_square(self):
        for line_square_index in range(3):
            for column_square_index in range(3):
                variable_names = []
                line_index_start = line_square_index * 3
                for line_index in range(line_index_start, line_index_start + 3):
                    column_index_start = column_square_index * 3
                    for column_index in range(column_index_start, column_index_start + 3):
                        variable_names.append(self._variable_name(line_index, column_index))
                self._problem.addConstraint(AllDifferentConstraint(), variable_names)

    def generate_constraints(self):
        self._each_once_per_line()
        self._each_once_per_column()
        self._each_once_per_square()

    def _variable_name(self, line_index, column_index):
        return '(l%d,c%d)' % (line_index, column_index)

    def feed_puzzle(self, values_of_colum_of_line):
        for line_index, values_of_column in values_of_colum_of_line.items():
            for column_index, values in values_of_column.items():
                variable_name = self._variable_name(line_index, column_index)
                self._problem.addVariable(variable_name, values)

    def iterate_solutions(self):
        return self._problem.getSolutionIter()

    def format_solution(self, solution_dict, indent_text):
        chunks = []
        for line_index in range(9):
            values = []
            for column_index in range(9):
                value = solution_dict[self._variable_name(line_index, column_index)]
                values.append(value)
            chunks.append(indent_text + '%d %d %d | %d %d %d | %d %d %d' % tuple(values))

            if line_index % 3 == 2 and line_index < 8:
                chunks.append(indent_text + '------+-------+------')

        return '\n'.join(chunks)
Пример #44
0
def gen_disjunct_intervals_CSP(ints):
    p = Problem()
    size = len(ints)
    sizeL = range(size)
    for intnum, key in enumerate(ints):
        values = [[]]
        for i in sizeL:
            values += [
                item
                for item in it.combinations(ints, i + 1) if key in item
            ]
        p.addVariable(intnum, values)

    for i in sizeL:
        p.addConstraint(check_continuity, (i,))
    for i1, i2 in it.product(sizeL, sizeL):
        if i1 < i2:
            p.addConstraint(check_all, (i1, i2))
    p.addConstraint(all_interval, sizeL)

    return p.getSolution()
Пример #45
0
def solve_board(board, cages):
    problem = Problem()
    height = len(board)
    width = len(board[0])
    assert width == height, 'Grid must be a square'

    cage_name_to_locations = defaultdict(list)

    for x in range(height):
        row_variables = [(x, ry) for ry in range(width)]
        column_variables = [(cx, x) for cx in range(height)]
        problem.addConstraint(AllDifferentConstraint(), row_variables)
        problem.addConstraint(AllDifferentConstraint(), column_variables)
        for y in range(width):
            if isinstance(board[x][y], basestring):
                # we are dealing with a function
                cage_name_to_locations[board[x][y]].append((x, y))
            else:
                # we are dealing with a pre-assigned number
                problem.addVariable((x, y), [board[x][y]])

    for cage_name, cage_locations in cage_name_to_locations.iteritems():
        cage_function = cages[cage_name]
        all_values = product(range(1, width + 1),
                             repeat=len(cage_locations))
        possible_values = set(chain(*[values for values in all_values
                                      if cage_function(*values)]))
        for location in cage_locations:
            problem.addVariable(location, list(possible_values))
        problem.addConstraint(FunctionConstraint(cage_function),
                              cage_locations)

    solution = problem.getSolution()

    answer = [row[:] for row in board]
    for x in range(height):
        for y in range(width):
            answer[x][y] = solution[(x, y)]

    return answer
Пример #46
0
def solve(sudoku_data):
    """ Solves the sudoku using simple constraints programming.
    Returns a list of solutions. Multiple solutions may be found if
    the sudoku wasn't parsed correctly.
    """
    problem = Problem()
    # add known numbers
    for i in range(0, 81):
        problem.addVariable(i, [int(sudoku_data[i])]
                                   if sudoku_data[i]
                                   else range(1, 10))
    for i in range(0, 9):
        # row constraint
        problem.addConstraint(AllDifferentConstraint(),
                              range(i * 9, i * 9 + 9))
        # column constraint
        problem.addConstraint(AllDifferentConstraint(),
                              [(i + 9 * c) for c in range(0, 9)])
        # box constraint
        problem.addConstraint(AllDifferentConstraint(),
                              [(i * 3) + (i / 3 * 18) + (9 * j) + k
                                  for j in range(0, 3)
                                    for k in range(0, 3)])
    return problem.getSolutions()
Пример #47
0
def derive_depths(original_markers, additional_constraints=[]):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if not original_markers:
        return []
    problem = Problem()
    marker_list = _compress_markerless(original_markers)

    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0",))

    all_vars = []
    for idx, marker in enumerate(marker_list):
        type_var = "type{}".format(idx)
        depth_var = "depth{}".format(idx)
        # Index within the marker list. Though this variable is redundant, it
        # makes the code easier to understand and doesn't have a significant
        # performance penalty
        idx_var = "idx{}".format(idx)

        typ_opts = [t for t in markers.types if marker in t]
        idx_opts = [i for t in typ_opts for i in range(len(t))
                    if t[i] == marker]
        problem.addVariable(type_var, typ_opts)
        problem.addVariable(idx_var, idx_opts)

        problem.addConstraint(rules.type_match(marker), [type_var, idx_var])
        all_vars.extend([type_var, idx_var, depth_var])

        if idx > 0:
            pairs = all_vars[3*(idx-1):]
            problem.addConstraint(rules.depth_check, pairs)

        if idx > 1:
            pairs = all_vars[3*(idx-2):]
            problem.addConstraint(rules.markerless_sandwich, pairs)
            problem.addConstraint(rules.star_sandwich, pairs)

    # separate loop so that the simpler checks run first
    for idx in range(1, len(marker_list)):
        # start with the current idx
        params = all_vars[3*idx:3*(idx+1)]
        # then add on all previous
        params += all_vars[:3*idx]
        problem.addConstraint(rules.sequence, params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_parent_same_type, all_vars)
    problem.addConstraint(rules.stars_occupy_space, all_vars)

    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    solutions = []
    for assignment in problem.getSolutionIter():
        assignment = _decompress_markerless(assignment, original_markers)
        solutions.append(Solution(assignment))
    return solutions
Пример #48
0
def solve():
    problem = Problem()
    for i in range(1, 6):
        problem.addVariable("color%d" % i,
                            ["red", "white", "green", "yellow", "blue"])
        problem.addVariable("nationality%d" % i,
                            ["brit", "swede", "dane", "norwegian", "german"])
        problem.addVariable("drink%d" % i,
                            ["tea", "coffee", "milk", "beer", "water"])
        problem.addVariable("smoke%d" % i,
                            ["pallmall", "dunhill", "blends",
                             "bluemaster", "prince"])
        problem.addVariable("pet%d" % i,
                            ["dogs", "birds", "cats", "horses", "fish"])

    problem.addConstraint(AllDifferentConstraint(),
                          ["color%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["nationality%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["drink%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["smoke%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["pet%d" % i for i in range(1, 6)])

    for i in range(1, 6):

        # Hint 1
        problem.addConstraint(lambda nationality, color:
                              nationality != "brit" or color == "red",
                              ("nationality%d" % i, "color%d" % i))

        # Hint 2
        problem.addConstraint(lambda nationality, pet:
                              nationality != "swede" or pet == "dogs",
                              ("nationality%d" % i, "pet%d" % i))

        # Hint 3
        problem.addConstraint(lambda nationality, drink:
                              nationality != "dane" or drink == "tea",
                              ("nationality%d" % i, "drink%d" % i))

        # Hint 4
        if i < 5:
            problem.addConstraint(lambda colora, colorb:
                                  colora != "green" or colorb == "white",
                                  ("color%d" % i, "color%d" % (i + 1)))
        else:
            problem.addConstraint(lambda color: color != "green",
                                  ("color%d" % i,))

        # Hint 5
        problem.addConstraint(lambda color, drink:
                              color != "green" or drink == "coffee",
                              ("color%d" % i, "drink%d" % i))

        # Hint 6
        problem.addConstraint(lambda smoke, pet:
                              smoke != "pallmall" or pet == "birds",
                              ("smoke%d" % i, "pet%d" % i))

        # Hint 7
        problem.addConstraint(lambda color, smoke:
                              color != "yellow" or smoke == "dunhill",
                              ("color%d" % i, "smoke%d" % i))

        # Hint 8
        if i == 3:
            problem.addConstraint(lambda drink: drink == "milk",
                                  ("drink%d" % i,))

        # Hint 9
        if i == 1:
            problem.addConstraint(lambda nationality:
                                  nationality == "norwegian",
                                  ("nationality%d" % i,))

        # Hint 10
        if 1 < i < 5:
            problem.addConstraint(lambda smoke, peta, petb:
                                  smoke != "blends" or peta == "cats" or
                                  petb == "cats",
                                  ("smoke%d" % i, "pet%d" % (i - 1),
                                                  "pet%d" % (i + 1)))
        else:
            problem.addConstraint(lambda smoke, pet:
                                  smoke != "blends" or pet == "cats",
                                  ("smoke%d" % i,
                                   "pet%d" % (i == 1 and 2 or 4)))

        # Hint 11
        if 1 < i < 5:
            problem.addConstraint(lambda pet, smokea, smokeb:
                                  pet != "horses" or smokea == "dunhill" or
                                  smokeb == "dunhill",
                                  ("pet%d" % i, "smoke%d" % (i - 1),
                                                "smoke%d" % (i + 1)))
        else:
            problem.addConstraint(lambda pet, smoke:
                                  pet != "horses" or smoke == "dunhill",
                                  ("pet%d" % i,
                                   "smoke%d" % (i == 1 and 2 or 4)))

        # Hint 12
        problem.addConstraint(lambda smoke, drink:
                              smoke != "bluemaster" or drink == "beer",
                              ("smoke%d" % i, "drink%d" % i))

        # Hint 13
        problem.addConstraint(lambda nationality, smoke:
                              nationality != "german" or smoke == "prince",
                              ("nationality%d" % i, "smoke%d" % i))

        # Hint 14
        if 1 < i < 5:
            problem.addConstraint(lambda nationality, colora, colorb:
                                  nationality != "norwegian" or
                                  colora == "blue" or colorb == "blue",
                                  ("nationality%d" % i, "color%d" % (i - 1),
                                                        "color%d" % (i + 1)))
        else:
            problem.addConstraint(lambda nationality, color:
                                  nationality != "norwegian" or
                                  color == "blue",
                                  ("nationality%d" % i,
                                   "color%d" % (i == 1 and 2 or 4)))

        # Hint 15
        if 1 < i < 5:
            problem.addConstraint(lambda smoke, drinka, drinkb:
                                  smoke != "blends" or
                                  drinka == "water" or drinkb == "water",
                                  ("smoke%d" % i, "drink%d" % (i - 1),
                                                  "drink%d" % (i + 1)))
        else:
            problem.addConstraint(lambda smoke, drink:
                                  smoke != "blends" or drink == "water",
                                  ("smoke%d" % i,
                                   "drink%d" % (i == 1 and 2 or 4)))

    solutions = problem.getSolutions()
    return solutions
Пример #49
0
def main(puzzle, lines):
    puzzle = puzzle.rstrip().splitlines()
    while puzzle and not puzzle[0]:
        del puzzle[0]

    # Extract horizontal words
    horizontal = []
    word = []
    predefined = {}
    for row in range(len(puzzle)):
        for col in range(len(puzzle[row])):
            char = puzzle[row][col]
            if not char.isspace():
                word.append((row, col))
                if char != "#":
                    predefined[row, col] = char
            elif word:
                if len(word) > MINLEN:
                    horizontal.append(word[:])
                del word[:]
        if word:
            if len(word) > MINLEN:
                horizontal.append(word[:])
            del word[:]

    # Extract vertical words
    vertical = []
    validcol = True
    col = 0
    while validcol:
        validcol = False
        for row in range(len(puzzle)):
            if col >= len(puzzle[row]):
                if word:
                    if len(word) > MINLEN:
                        vertical.append(word[:])
                    del word[:]
            else:
                validcol = True
                char = puzzle[row][col]
                if not char.isspace():
                    word.append((row, col))
                    if char != "#":
                        predefined[row, col] = char
                elif word:
                    if len(word) > MINLEN:
                        vertical.append(word[:])
                    del word[:]
        if word:
            if len(word) > MINLEN:
                vertical.append(word[:])
            del word[:]
        col += 1

    # hnames = ["h%d" % i for i in range(len(horizontal))]
    # vnames = ["v%d" % i for i in range(len(vertical))]

    # problem = Problem(MinConflictsSolver())
    problem = Problem()

    for hi, hword in enumerate(horizontal):
        for vi, vword in enumerate(vertical):
            for hchar in hword:
                if hchar in vword:
                    hci = hword.index(hchar)
                    vci = vword.index(hchar)
                    problem.addConstraint(lambda hw, vw, hci=hci, vci=vci:
                                          hw[hci] == vw[vci],
                                          ("h%d" % hi, "v%d" % vi))

    for char, letter in predefined.items():
        for hi, hword in enumerate(horizontal):
            if char in hword:
                hci = hword.index(char)
                problem.addConstraint(lambda hw, hci=hci, letter=letter:
                                      hw[hci] == letter, ("h%d" % hi,))
        for vi, vword in enumerate(vertical):
            if char in vword:
                vci = vword.index(char)
                problem.addConstraint(lambda vw, vci=vci, letter=letter:
                                      vw[vci] == letter, ("v%d" % vi,))

    wordsbylen = {}
    for hword in horizontal:
        wordsbylen[len(hword)] = []
    for vword in vertical:
        wordsbylen[len(vword)] = []

    for line in lines:
        line = line.strip()
        l = len(line)
        if l in wordsbylen:
            wordsbylen[l].append(line.upper())

    for hi, hword in enumerate(horizontal):
        words = wordsbylen[len(hword)]
        random.shuffle(words)
        problem.addVariable("h%d" % hi, words)
    for vi, vword in enumerate(vertical):
        words = wordsbylen[len(vword)]
        random.shuffle(words)
        problem.addVariable("v%d" % vi, words)

    problem.addConstraint(AllDifferentConstraint())

    solution = problem.getSolution()
    if not solution:
        print("No solution found!")

    maxcol = 0
    maxrow = 0
    for hword in horizontal:
        for row, col in hword:
            if row > maxrow:
                maxrow = row
            if col > maxcol:
                maxcol = col
    for vword in vertical:
        for row, col in vword:
            if row > maxrow:
                maxrow = row
            if col > maxcol:
                maxcol = col

    matrix = []
    for row in range(maxrow + 1):
        matrix.append([" "] * (maxcol + 1))

    for variable in solution:
        if variable[0] == "v":
            word = vertical[int(variable[1:])]
        else:
            word = horizontal[int(variable[1:])]
        for (row, col), char in zip(word, solution[variable]):
            matrix[row][col] = char

    for row in range(maxrow + 1):
        for col in range(maxcol + 1):
            sys.stdout.write(matrix[row][col])
        sys.stdout.write("\n")
def solve():
    problem = Problem()
    problem.addVariables("sendmory", range(10))
    problem.addConstraint(lambda d, e, y: (d + e) % 10 == y, "dey")
    problem.addConstraint(lambda n, d, r, e, y: (n * 10 + d + r * 10 + e) % 100 == e * 10 + y, "ndrey")
    problem.addConstraint(
        lambda e, n, d, o, r, y: (e * 100 + n * 10 + d + o * 100 + r * 10 + e) % 1000 == n * 100 + e * 10 + y, "endory"
    )
    problem.addConstraint(
        lambda s, e, n, d, m, o, r, y: 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e
        == 10000 * m + 1000 * o + 100 * n + 10 * e + y,
        "sendmory",
    )
    problem.addConstraint(NotInSetConstraint([0]), "sm")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
Пример #51
0
fruits    = "grapes kiwi bananas peach grapefruit".split()

# There are five houses.
minn, maxn = 1, 5
problem = Problem()
# value of a variable is the number of a house with corresponding property
variables = colors + nationalities + pets + drinks + fruits
problem.addVariables(variables, range(minn, maxn+1))

# Each house has its own unique color.
# All house owners are of different nationalities.
# They all have different pets.
# They all drink different drinks.
# They all smoke different fruits.
for vars_ in (colors, nationalities, pets, drinks, fruits):
    problem.addConstraint(AllDifferentConstraint(), vars_)

# In the middle house they drink milk.
#NOTE: interpret "middle" in a numerical sense (not geometrical)
problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["milk"])
# The Norwegian lives in the first house.
#NOTE: interpret "the first" as a house number
problem.addConstraint(InSetConstraint([minn]), ["Norwegian"])
# The green house is on the left side of the white house.
#XXX: what is "the left side"? (linear, circular, two sides, 2D house arrangment)
#NOTE: interpret it as 'green house number' + 1 == 'white house number'
problem.addConstraint(lambda a,b: a+1 == b, ["green", "white"])

def add_constraints(constraint, statements, variables=variables, problem=problem):
    for stmt in (line for line in statements if line.strip()):
        print [v for v in variables if v in stmt]
Пример #52
0
def solve():
    problem = Problem()

    # Define the variables: 9 rows of 9 variables rangin in 1...9
    for i in range(1, 10):
        problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10))

    # Each row has different values
    for i in range(1, 10):
        problem.addConstraint(AllDifferentConstraint(), range(i * 10 + 1, i * 10 + 10))

    # Each colum has different values
    for i in range(1, 10):
        problem.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10))

    # Each 3x3 box has different values
    problem.addConstraint(AllDifferentConstraint(), [11, 12, 13, 21, 22, 23, 31, 32, 33])
    problem.addConstraint(AllDifferentConstraint(), [41, 42, 43, 51, 52, 53, 61, 62, 63])
    problem.addConstraint(AllDifferentConstraint(), [71, 72, 73, 81, 82, 83, 91, 92, 93])

    problem.addConstraint(AllDifferentConstraint(), [14, 15, 16, 24, 25, 26, 34, 35, 36])
    problem.addConstraint(AllDifferentConstraint(), [44, 45, 46, 54, 55, 56, 64, 65, 66])
    problem.addConstraint(AllDifferentConstraint(), [74, 75, 76, 84, 85, 86, 94, 95, 96])

    problem.addConstraint(AllDifferentConstraint(), [17, 18, 19, 27, 28, 29, 37, 38, 39])
    problem.addConstraint(AllDifferentConstraint(), [47, 48, 49, 57, 58, 59, 67, 68, 69])
    problem.addConstraint(AllDifferentConstraint(), [77, 78, 79, 87, 88, 89, 97, 98, 99])

    # Some value is given.
    initValue = [
        [0, 9, 0, 7, 0, 0, 8, 6, 0],
        [0, 3, 1, 0, 0, 5, 0, 2, 0],
        [8, 0, 6, 0, 0, 0, 0, 0, 0],
        [0, 0, 7, 0, 5, 0, 0, 0, 6],
        [0, 0, 0, 3, 0, 7, 0, 0, 0],
        [5, 0, 0, 0, 1, 0, 7, 0, 0],
        [0, 0, 0, 0, 0, 0, 1, 0, 9],
        [0, 2, 0, 6, 0, 0, 0, 5, 0],
        [0, 5, 4, 0, 0, 8, 0, 7, 0],
    ]

    for i in range(1, 10):
        for j in range(1, 10):
            if initValue[i - 1][j - 1] != 0:
                problem.addConstraint(lambda var, val=initValue[i - 1][j - 1]: var == val, (i * 10 + j,))

    # Get the solutions.
    solutions = problem.getSolutions()
    return solutions
Пример #53
0
from constraint import Problem, AllDifferentConstraint
from itertools import product
from functools import partial

columns = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
rows = [1, 2, 3, 4, 5, 6, 7, 8]

mapping = dict((x, y) for x, y in zip(columns, rows))

def bishop_func(a, b, x, y): return abs(mapping[x] - mapping[y]) != abs(a - b) or a == b

problem = Problem()

problem.addVariables(columns, rows)
problem.addConstraint(AllDifferentConstraint())

for column1, column2 in product(columns, columns):
    problem.addConstraint(partial(bishop_func, x = column1, y = column2), (column1, column2))

for solution in problem.getSolutions():
    print sorted(solution.iteritems())


Пример #54
0
class GraphletsConstraints(RWEngineBase):
    
    __printConds = False
    
    def __init__(self,nodeGradesInfos):
        self.nodeGradesInfos = nodeGradesInfos
        self.sol = None
    
    
    # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+"
    def breakCommand(self,cmd):
        cmdFields = seperateCmd(cmd)
        if len(cmdFields) ==0:
            print "asd"
        assert (len(cmdFields) >0)
        if len(cmdFields) == 1 :
            return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':[]}
        else:
            return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':cmdFields[-1].split(",")}
    
    
    #TODO - add to this..
    lvalCmdsStarts = ["mov","sub","add","xor"]
    
    def getNemonicType(self,nemonic):
        if any(map(lambda startString: nemonic.startswith(startString),self.lvalCmdsStarts)):
            return "WriteThenRead"
        else:
            return "Read"
    
    FuncPrefix = "f"
    VARPrefix = "s"
    RegisterPrefix = "r"
    OffsetPrefix = "o"
    OtherPrefix = "X"
    
    def getPrefix(self,Str):
        if isVarStr(Str):
            return self.VARPrefix
        elif isRegisterStr(Str):
            return self.RegisterPrefix
        elif isOffset(Str):
            return self.OffsetPrefix
        else:
            return self.OtherPrefix 
            

    def varsEqual(self,v1, v2):
        return v1==v2
    
    def checkInputVsTarget(self,target):
        def retFunc(inputVal):
            return inputVal == target
        
        return retFunc     


    def getVarName(self,prefix,lineNumber,varsInThisLine):
        return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR"

    def getMembers(self,param):
        refMembers = param.split("+")
        refMembers[0] = refMembers[0][1:] #remove [ from first
        refMembers[-1] = refMembers[-1][0:-1]  # remove ] from last (they can be the same one!)
        return refMembers

    def getDomains(self):
        domains = {self.FuncPrefix:set(),self.VARPrefix:set(),self.RegisterPrefix:set(),self.OffsetPrefix:set()}
        
        def getCmdSymbols(cmd):
            cmdBasicInfo = self.breakCommand(cmd)
            for param in cmdBasicInfo['ParamsList']:
                if param.startswith("["):
                    for member in self.getMembers(param):
                        yield member
                else:
                    yield param
        
        def getCmds(cmdsDelimited):
            return filter(None,cmdsDelimited.split(";"))
        
        for cmdList in itertools.imap(lambda nodeGradesInfo:getCmds(nodeGradesInfo['refCode']),self.nodeGradesInfos):
            for cmd in cmdList:
                
                if isCall(cmd):
                    prefix = self.FuncPrefix
                    domains[prefix].add(list(getCmdSymbols(cmd))[0])
                else:
                    for symbol in getCmdSymbols(cmd):
                        prefix = self.getPrefix(symbol)
                        if prefix != self.OtherPrefix:
                            domains[prefix].add(symbol)
            
        for domainName in domains.keys():
            domains[domainName] = list(domains[domainName])
            
        return domains

    def callSol(self):
        
        
        domains = self.getDomains()
        
        #domains[refPrefix].add(refVal) 
        
        self.problem = Problem(MinConflictsSolver())
        
        tarSymbolsCache = {}
        
        self.varsInThisLine = 0
        
        def addInTraceletCons(tarVal,newVarName):
            if (self.__printConds):
                print "CONS(IN) -> " + tarSymbolsCache[tarVal] + " == " + newVarName 
            self.problem.addConstraint(self.varsEqual,[newVarName,tarSymbolsCache[tarVal]])
            
            
        def addCrossTraceletCons(refVal,newVarName,refPrefix):
            if (self.__printConds):
                print "CONS(CROSS) -> " + newVarName + " == " + refVal
            self.problem.addConstraint(self.checkInputVsTarget(refVal),[newVarName])
        
        
        def addVarWithPrefix(prefix,lineNumber):
            newVarName = self.getVarName(prefix,lineNumber,self.varsInThisLine)
            if len(domains[prefix]) == 0:
                print "EMP"
            self.problem.addVariables([newVarName],domains[prefix])
            self.varsInThisLine+=1
            return newVarName
        
        
        # mode can be - WRITE or NORMAL
        def doDF(refSymbol,tarSymbol,lineNumber,refPrefix,tarPrefix,nemonicType):
            
            if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix:
                return 
            
            newVarName = addVarWithPrefix(tarPrefix,lineNumber)
            
            if (refPrefix == tarPrefix):
                addCrossTraceletCons(refSymbol,newVarName,refPrefix)
        
            if tarSymbol in tarSymbolsCache:  
                addInTraceletCons(tarSymbol,newVarName)
                
            if tarPrefix != self.RegisterPrefix or nemonicType=="WriteThenRead":
                tarSymbolsCache[tarSymbol] = newVarName
        
        
        #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)):
        
        tarBase = 0
        refBase = 0
        
        for nodeInfo in self.nodeGradesInfos:
            for matchedCmd in nodeInfo['matchedCmds']:
                
                self.varsInThisLine = 1
        
                # if these cmds are not an operational match, we cannot cross tracelet match them.
                if matchedCmd['operationMatch'] == True:
                    
                    currentLineNumber = tarBase + matchedCmd['tarCmdNum'] #  matchedCmd['tarCmdNum'] is 1 based so we are ok
                    
                    if matchedCmd['tar'] =="" or matchedCmd['ref'] =="":
                        continue
                    
                    tarCmdBasicInfo = self.breakCommand(matchedCmd['tar'])
                    refCmdBasicInfo = self.breakCommand(matchedCmd['ref'])
                    if len(tarCmdBasicInfo['ParamsList'])>0 and len(refCmdBasicInfo['ParamsList'])>0:
                        
                        if tarCmdBasicInfo['nemonic'] == 'call':
                            
                            assert(len(refCmdBasicInfo['ParamsList'])==1)
                            assert(len(tarCmdBasicInfo['ParamsList'])==1)
                            
                            doDF(refCmdBasicInfo['ParamsList'][0], tarCmdBasicInfo['ParamsList'][0], currentLineNumber, self.FuncPrefix,self.FuncPrefix, "Read")
                        else:
                        
                            nemonicType = self.getNemonicType(tarCmdBasicInfo['nemonic'])
                            
                            for (refParam,tarParam) in zip(refCmdBasicInfo['ParamsList'],tarCmdBasicInfo['ParamsList']):
                                
                                tarIsMem = "[" in tarParam
                                if tarIsMem != ("[" in refParam):
                                    continue
                                    print matchedCmd
                                    print "BOY"
                                
                                assert  tarIsMem == ("[" in refParam)
                                
                                if not tarIsMem:
                                    tarPreFix = self.getPrefix(tarParam)
                                    refPreFix = self.getPrefix(refParam)
                                    
                                    doDF(refParam, tarParam, currentLineNumber, tarPreFix,refPreFix, nemonicType)
                                      
                                      
                                    # TODO - return this to find more classes when we have time...
                                    """
                                    if nemonicType == "WriteThenRead":  
                                        if tarPreFix != self.RegisterPrefix:
                                            print matchedCmd
                                        
                                        assert (tarPreFix == self.RegisterPrefix)
                                        # the write is only to the left most param, rest are normal
                                    """
                                else:
                                    # this is memory! , first remove '[',']'
    
                                    for (refMember,tarMember) in zip(self.getMembers(refParam),self.getMembers(tarParam)):
                                        tarPreFix = self.getPrefix(tarMember)
                                        refPreFix = self.getPrefix(refMember)
                                        doDF(refMember, tarMember, currentLineNumber, tarPreFix,refPreFix, nemonicType)
                                        
                                nemonicType = "Read"
                                        
                                        
                    #TODO handle the False clause ?
                     
            tarBase += nodeInfo['tarCode'].count(";")
            refBase += nodeInfo['refCode'].count(";")
                    
                   
            
        self.sol = self.problem.getSolution()
        
        #print self.sol
    
    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
    
    # TODO - make this __
    def getRW(self):
        sol = self.getSolution()
        
        tarBase = 0
               
        symbolsCache = {}
        
        self.varsInThisLine = 0
        TotalLineNumber = 0
        
        def getRewrittenSymbolUpdateCache(prefix,symbol):
            varName = self.getVarName(prefix, TotalLineNumber, self.varsInThisLine)
            if sol != None and varName in sol:
                symbolsCache[symbol] = sol[varName]
                return sol[varName]
            else:
                return symbol
        
        def rewrittenParam(param):
            if param.startswith("["):
                rewrittenMembers = []
                for member in self.getMembers(param):
                    rewrittenMembers.append(getRewrittenSymbolUpdateCache(self.getPrefix(member), member))
                    self.varsInThisLine+=1
                return "[" + "+".join(rewrittenMembers) + "]"
            else:
                newParam = getRewrittenSymbolUpdateCache(self.getPrefix(param), param)
                self.varsInThisLine+=1
                return newParam
               
        
        for nodeInfo in self.nodeGradesInfos:
        
            cmdsStr = nodeInfo['tarCode']
            rewrittenCmds = []
    
            lastLineNumber = 0 #filter(None,)
            for (lineNumber,cmd) in enumerate(cmdsStr.split(";")):
                
                TotalLineNumber = tarBase + lineNumber + 1 # we are one based
                lastLineNumber = lineNumber +1  # we are one based
                
                self.varsInThisLine = 1
                
                if cmd != "":
                    tarCmdBasicInfo = self.breakCommand(cmd)
                    if len(tarCmdBasicInfo['ParamsList'])>0:
                        if tarCmdBasicInfo['nemonic'] == 'call':
                            rewrittenCmds.append("call " + getRewrittenSymbolUpdateCache(self.FuncPrefix,tarCmdBasicInfo['ParamsList'][0]))
                        else:
                            rewrittenCmds.append(tarCmdBasicInfo['nemonicWithDecoretors'] + " " + ",".join(map(rewrittenParam,tarCmdBasicInfo['ParamsList'])))
                    else:
                        rewrittenCmds.append(cmd)
                else:
                    # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned)
                    rewrittenCmds.append(cmd)
            
            tarBase += lastLineNumber-1
    
            yield ";".join(rewrittenCmds)
        
        
    def getSolution(self):
        if self.sol == None:
            self.callSol()
            
        return self.sol
    
    def printSol(self,sol):
        #better call sol!
        
        if sol == None:
            print "NO SOL!"
            return
        
        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""
            
            print key + ": " + sol[key] + " ", 
Пример #55
0
class GraphletsConstraints(X86AnalyzerBase):
    
    #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"]
    
    __dictNames = ['ref','tar']
    
    __printConds = False
    
    def __init__(self,nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self,nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it
        
        # TODO make __
        self.sol = None 
        
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1
        
        self.createRewrite()
    
    def getEmptyDict(self):
        d = X86AnalyzerBase.getEmptyDict(self)
        for key in d.keys():
            d[key]['transitions'] = []
            d[key]['valuesTrackDict'] = {}
            #if key != self.REGISTER:
            d[key]['domain'] = set()
            #self.rewriteDict[key]['inCmdCounter'] = 1
            
        return d
    
    # this will add recorded value to dict, even if there is a conflict it will be recorded...
    #
    def insertToDictWithType(self,tarCmdNum,fromStr,refCmdNum,toStr,typeStr,dict2insert=None):

        assert(dict2insert != None)
        dict2insert[typeStr]['transitions'].append((tarCmdNum,fromStr,toStr))
        
        #if typeStr != self.REGISTER:
        dict2insert[typeStr]['domain'].add(toStr)
            

    def commitChanges(self,tmpDict):
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['transitions'].extend(tmpDict[key]['transitions'])
            #if key != self.REGISTER:
            self.rewriteDict[key]['domain'].update(tmpDict[key]['domain'])
        

    # black list has no generation:) , we can use the rwdict type as they are the same..
    def getRewriteWithType(self,tarCmdNum,fromStr,typeStr,FoundBlacklistElement):
        
        if self.sol == None:
            self.callSol()

        if self.rewriteDict[typeStr]['curLine'] < tarCmdNum :
            self.rewriteDict[typeStr]['curLine'] = tarCmdNum
            self.rewriteDict[typeStr]['curPos'] = 1

            
        varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos'])
        self.rewriteDict[typeStr]['curPos'] += 1
        
        if self.sol != None and varName in self.sol:
            # we have a value! update cache and return it
            newVal = self.sol[varName]
            self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal
            return newVal
        elif fromStr in self.rewriteDict[typeStr]['symbolCache']:
            return self.rewriteDict[typeStr]['symbolCache'][fromStr]
        else:
            #not found in this type's map in this generation, return original
            return fromStr

    def getShort(self,name):
        if name == self.FUNCNAME:
            return "f"
        elif name == self.VAR:
            return "m"
        elif name == self.REGISTER:
            return "r"
        else :
            raise hell
        
    def getVarName(self,preFix,curLine,curPos):
        return preFix + str(curLine) + "-" + str(curPos) + "_TAR"

    # TODO - make this __
    def callSol(self):
        # we need to go over each dict that is useable, and feed vars and constraints
        for typeDict in [x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble']==True ]:
            curLine = 1
            curPos = 1
            
            preFix = self.getShort(typeDict)
            #if typeDict != self.REGISTER:
            domain = list(self.rewriteDict[typeDict]['domain']) 
            #else:
            #    domain =self.__registers32Bit
            for (line,tarStr,refStr) in self.rewriteDict[typeDict]['transitions']:
                if curLine < line:
                    curPos = 1
                    curLine = line
                    
                tarName = self.getVarName(preFix, curLine, curPos)
                
                self.problem.addVariables([tarName],domain)
                if (self.__printConds):
                    print "CONS(text) -> " + tarName + " == " + refStr 
                self.problem.addConstraint(self.checkInputVsTarget(refStr),[tarName])
                
            
                if tarStr in self.rewriteDict[typeDict]['valuesTrackDict'] != None:
                    if (self.__printConds):
                        print "CONS(bag) -> " + self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] + " == " + tarName 
                    self.problem.addConstraint(self.varsEqual,[tarName,self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]])
                self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName
                        
                curPos+=1
                
        self.sol = self.problem.getSolution()
        if traceHack:
            print "(Number of broken - " + str(self.problem.getSolver().getHack()) + ")",

    def varsEqual(self,v1, v2):
        return v1==v2
    
    def checkInputVsTarget(self,target):
        def retFunc(inputVal):
            return inputVal == target
        
        return retFunc     
    
               
    def getSolution(self):
        if self.sol == None:
            self.callSol()
            
        return self.sol
    
    def printSol(self,sol):
        #better call sol!
        
        if sol == None:
            print "NO SOL!"
            return
        
        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""
            
            print key + ": " + sol[key] + " ",
             
    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()