Beispiel #1
0
def convert_to_CNF(p, verbose=False):
    """
    Pretvorba formule v CNF.
    p - formula za pretvorbo
    verbose - zastavica za izpis poteka funkcije

    Vrne formulo p v CNF obliki.
    """
    def convert_to_cnf_aux(f):
        """
        Prevede funkcijo v CNF obliko.
        Kot vhod prejme funkcijo. Funkcija mora biti v primerni obliki (negacije
        so lahko le pred spremenljivkami).
        """
        if isinstance(f, (V, Not, Tru, Fls)):
            return f
        if isinstance(f, And):
            combined = []   # Ze v cnf obliki, samo zdruzimo skupaj posamezne konjunkcije.
            for p in f.formule:
                combined.append(convert_to_cnf_aux(p))
            return simplify(And(combined))
        if isinstance(f, Or):
            combined = []   # Moramo pretvoriti v CNF.
            for p in f.formule:
                combined.append(convert_to_cnf_aux(p))
            # Pretvorimo tako, da naredimo vse mozne kombinacije med konjunkcijo in disjunkcijo.
            combined = kombinacije(combined)
            comb2 = []
            for p in combined:
                comb2.append(Or(p))
            return And(comb2)

    def simp_cnf(cs, verbose=False):
        """
        Nadaljnje poenostavljanje.
        """
        if isinstance(cs, Tru):
            if verbose:
                print "Tru", cs
            return splosci(cs)
        if isinstance(cs, Fls):
            if verbose:
                print "Fls", cs
            return And([Or([])])
        if isinstance(cs, V):
            if verbose:
                print "Variabla", cs
            return splosci(Or([cs]))
        if isinstance(cs, Not):
            if verbose:
                print "Not", cs
            return splosci(Or([cs]))
        if isinstance(cs, And):
            if verbose:
                print "And", cs
            return splosci(And([simp_cnf(term, verbose) for term in cs.formule]))
        if isinstance(cs, Or):
            if not cs.formule:
                if verbose:
                    print "Or 0", cs
                return And([Or([])])
            elif len(cs.formule) == 1:
                if verbose:
                    print "Or 1", cs
                return splosci(simp_cnf(cs.formule[0]))
            else:
                if verbose:
                    print "Or > 2", cs
                # Kompliciran Or, potrebna distribucija
                konj, ostalo = [], []
                for f in cs.formule:
                    if isinstance(f, And):
                        konj.append(f)
                    else:
                        ostalo.append(f)
                if not konj:
                    return splosci(Or(ostalo))
                else:
                    return splosci(And([simp_cnf(Or(ostalo+[el]+konj[1:]), verbose)
                                        for el in konj[0].formule]))

    # Osnovna pretvorba.
    tmp_cnf = simp_cnf(splosci(simplify(convert_to_cnf_aux(simplify_not((simplify(p)))))))

    # Robni primeri.
    if isinstance(tmp_cnf, V) or isinstance(tmp_cnf, Not) or isinstance(tmp_cnf, Fls):
        return And([Or([tmp_cnf])])
    if isinstance(tmp_cnf, Tru):
        return Tru()

    # Polovimo proste literatle.
    new_formule = []
    for f in tmp_cnf.formule:
        if isinstance(f, V) or isinstance(f, Not):
            new_formule.append(Or([f]))
        else:
            new_formule.append(f)

    return And(new_formule)
def hadamard_simplifed(n):
    """
    Vrne izraz primeren za vhod v DPLL.
    """
    return simplify_not(hadamardova_matrika(n))