Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
5.3 kB
1
Indexable
Never
def branching_sat_solve(clause_set, partial_assignment=None, truth_assignment=None, backtrack_idx=-1, idx=-1):
    # Generate a truth assignment if it's not there
    if not truth_assignment:
        max_literal = -1
        # Extract all the literals, and set them initially to False.
        for clause in clause_set:
            abs_clause = list(map(lambda x: abs(x), clause))
            if max(abs_clause) > max_literal:
                max_literal = max(abs_clause)

        if partial_assignment:
            abs_partial_assignment = list(map(lambda x: abs(x), partial_assignment))
            truth_assignment = [-1 * num for num in range(1, max_literal + 1) if num not in abs_partial_assignment] + partial_assignment
            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx, idx=idx)

        else:
            truth_assignment = [-1 * num for num in range(1, max_literal + 1)]
            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx, idx=idx)

    # Check if the truth assignment satisfies the clause set
    else:
        num_valid_clauses = 0
        for clause in clause_set:
            valid_clause = False
            for literal in truth_assignment:
                if literal in clause:
                    valid_clause = True
                    break

            if valid_clause:
                num_valid_clauses += 1

        # Clause set is satisfied, return truth assignment
        if num_valid_clauses == len(clause_set):
            return truth_assignment

        # Backtrack, start at last index
        else:
            try:
                if backtrack_idx == idx:
                    if partial_assignment:
                        if truth_assignment[backtrack_idx] in partial_assignment:
                            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx-1, idx=-1)

                        else:
                            if truth_assignment[backtrack_idx] < 0:
                                # Try negation of literal at backtrack idx
                                truth_assignment[backtrack_idx] = -1 * truth_assignment[backtrack_idx]

                                # Call func with backtrack_idx - 1, idx at the end
                                return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment,
                                                           truth_assignment=truth_assignment,
                                                           backtrack_idx=backtrack_idx - 1, idx=-1)

                            else:
                                truth_assignment[backtrack_idx] = -1 * truth_assignment[backtrack_idx]
                                return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment,
                                                           truth_assignment=truth_assignment,
                                                           backtrack_idx=backtrack_idx - 1, idx=-1)
                    else:
                        if truth_assignment[backtrack_idx] < 0:
                            # Try negation of literal at backtrack idx
                            truth_assignment[backtrack_idx] = -1 * truth_assignment[backtrack_idx]

                            # Call func with backtrack_idx - 1, idx at the end
                            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx - 1, idx=-1)

                        else:
                            truth_assignment[backtrack_idx] = -1 * truth_assignment[backtrack_idx]
                            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx - 1, idx=-1)

                else:
                    if partial_assignment:
                        # If the literal at truth_assignment[idx] is in the partial assignment, we skip past it.
                        if truth_assignment[idx] in partial_assignment:
                            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx, idx=idx - 1)

                        else:
                            truth_assignment[idx] = -1 * truth_assignment[idx]
                            return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment,
                                                       truth_assignment=truth_assignment, backtrack_idx=backtrack_idx,
                                                       idx=idx - 1)

                    else:
                        truth_assignment[idx] = -1 * truth_assignment[idx]
                        return branching_sat_solve(clause_set=clause_set, partial_assignment=partial_assignment, truth_assignment=truth_assignment, backtrack_idx=backtrack_idx, idx=idx-1)

            except IndexError:
                return 'unsat'