Beispiel #1
0
def createComparatorCnf(outputs: set, prefix1: str,
                        prefix2: str) -> (Cnf, SatVar):
    '''The function createComparatorCnf takes the common outputs of the circuits being checked,
    taking into account their differente prefixes, and builds the output miter logic
    with its XOR and OR gates. Its output is both the miter output CNF and the SatVar
    variable for the miter output symbol
    '''
    # Generation of XOR gates for miter circuit output
    comparator = Cnf()
    comp_signals = []
    i = 0
    for output in outputs:
        xor_i = SatVar('xor_' + str(i))
        output1 = SatVar(prefix1 + output)
        output2 = SatVar(prefix2 + output)
        comparator &= gate_xor(output1, output2, xor_i)
        comp_signals.append(xor_i)
        i += 1

    # Generation of OR gates for miter circuit output
    or_neutral = SatVar('or_neutral')
    comparator &= (~or_neutral)
    i = 0
    for xor_i in comp_signals:
        out = SatVar('or_' + str(i))
        curr = xor_i
        if i == 0:
            comparator &= gate_or(or_neutral, xor_i, out)
        else:
            prev = SatVar('or_' + str(i - 1))
            comparator &= gate_or(prev, xor_i, out)
        i += 1

    return comparator, out
def transform(c: Circuit, prefix: str='') -> Cnf:
    '''The function transform takes a Circuit c and returns a Cnf obtained by the
    Tseitin transformation of c. The optional prefix string will be used for
    all variable names in the Cnf.

    '''
    inputs.clear()
    signals.clear()
    solution = Cnf()

    # Filling input dictionary
    for in_str in c.getInputs():
        inputs[in_str] = SatVar(prefix + in_str)

    # Filling signals dictionary (outputs and internal signals)
    for sig_str in c.getSignals():
        signals[sig_str] = SatVar(prefix + sig_str)

    # Obtaining the CNFs for each signal (either intern or output)
    for sig_str in c.getSignals():
        node = c.getEquation(sig_str)
        solution = solution & transform_node(node, signals[sig_str], c)

    return solution
    pass
Beispiel #3
0
def transform(c: Circuit, prefix: str = '') -> Cnf:

    myCnf = Cnf()
    inputs = c.getSignals()

    #On parcourt l'ensemble des inputs pour trouver la transformation Tseitin
    for signal in inputs:
        mySatVar = SatVar(prefix + signal)
        node = c.getEquation(signal)
        child = node.getChildren()

        # Il y a une erreur dans test.py : Did not find value for output signal 's_8' in solution
        # En se rendant dans cra8.crc, on se rend compte qu'il y a une opération d'affection :
        # 	s_8 = x19
        # On crée donc la fonction EQ dans le fichier adder.py qui est simplement
        # une opération d'égalité nécessaire pour passer le test de cra8.crc
        if type(node).__name__ == "Variable":
            SatVarName = SatVar(prefix + node.getName())
            myCnf = myCnf & EQ(SatVarName, mySatVar)

        if type(node).__name__ == "Literal":
            myCnf = LiteralNode(node, mySatVar, myCnf)

        if type(node).__name__ == "BinOp":
            myCnf = BinOpNode(node, mySatVar, myCnf, prefix)

        if type(node).__name__ == "UnOp":
            myCnf = UnOpNode(node, mySatVar, myCnf, prefix)

    return myCnf
Beispiel #4
0
def createInputCnf(inputs: set, prefix1: str, prefix2: str) -> Cnf:
    '''The fucntion createInputCnf takes the common inputs of the circuits being checked,
    taking into account their different prefixes, and builds the input connections required
    by the miter circuit logic. Its output is the cnf representing these connections
    '''
    inputCnf = Cnf()

    for i in inputs:
        inputCnf &= equivalent(SatVar(i), SatVar(prefix1 + i))
        inputCnf &= equivalent(SatVar(i), SatVar(prefix2 + i))

    return inputCnf
def transform_node(n: Node, out: SatVar, c: Circuit) -> Cnf:
    '''The function transformNode recursively analyses the nodes objects it receives and 
    builds the corresponding CNF. Each step's output is its node's CNF so that the final
    execution has the complete CNF for a given node.
    '''
    cnf = Cnf()

    # Child nodes analysis for operation nodes
    children = []
    for child in n.getChildren():
        if isinstance(child, Literal):
            lit = SatVar('l_' + str(child.getID()))
            children.append(lit)
            if child.getValue() == True:
                cnf &= lit
            else:
                cnf &= ~lit
        elif isinstance(child, Variable):
            if child.getName() in inputs:
                var = inputs[child.getName()]
            elif child.getName() in signals:
                var = signals[child.getName()]
            children.append(var)
        elif isinstance(child, OpNode):
            internal = SatVar('y_' + str(child.getID()))
            children.append(internal)
            cnf &= transform_node(child, internal, c)

    # CNF building
    if isinstance(n, OpNode):
        if len(children) == 1:
            if n.getOp() == '~':
                cnf &= gate_not(children[0], out)
        elif len(children) == 2:
            if n.getOp() == '&':
                cnf &= gate_and(children[0], children[1], out)
            elif n.getOp() == '|':
                cnf &= gate_or(children[0], children[1], out)
            elif n.getOp() == '^':
                cnf &= gate_xor(children[0], children[1], out)
    elif isinstance(n, Variable):
            cnf &= equivalent(signals[n.getName()], out)
    elif isinstance(n, Literal):
            lit = SatVar('l_' + str(n.getID()))
            cnf &= equivalent(lit, out)
            if n.getValue() == True:
                cnf &= lit
            else:
                cnf &= ~lit

    return cnf
Beispiel #6
0
def transform(c: Circuit, prefix: str='') -> Cnf:
    '''The function transform takes a Circuit c and returns a Cnf obtained by the
    Tseitin transformation of c. The optional prefix string will be used for
    all variable names in the Cnf.
    '''

    cnf = Cnf()
    for keys in c.getSignals():
        s = SatVar(prefix+keys)
        node = c.getEquation(keys)

        children = node.getChildren()

        # This case should not really happen in a real circuit.
        if type(node).__name__ == "Variable":
            a = SatVar(prefix+node.getName())
            cnf = cnf & mk_eq(s, a)

        if type(node).__name__ == "Literal":
            if (node.getValue()):
                cnf = cnf & s
            else:
                cnf = cnf & ~s

        if type(node).__name__ == "BinOp":
            a, cnf1 = transform_rec(node.getChild(0), prefix)
            b, cnf2 = transform_rec(node.getChild(1), prefix)
            cnf = cnf & cnf1 & cnf2
            if (node.getOp() == "&"):
                cnf = cnf & mk_and(s, a, b)
            elif (node.getOp() == "^"):
                cnf = cnf & mk_xor(s, a, b)
            elif (node.getOp() == "|"):
                cnf = cnf & mk_or(s, a, b)
            else:
                raise ValueError("Unrecognized operator " + node.getOp())


        if type(node).__name__ == "UnOp":
            a, cnf1 = transform_rec(node.getChild(0), prefix)
            cnf = cnf & cnf1
            if (node.getOp() == "~"):
                cnf = cnf & mk_not(s, a)
            else:
                raise ValueError("Unrecognized operator " + node.getOp())

    return cnf
Beispiel #7
0
def transform_recursive(nd: Node, prefix: str = ''):

    newCnf = Cnf()

    if type(nd).__name__ == "Variable":
        newSatVarName = SatVar(prefix + nd.getName())
        return newSatVarName, newCnf

    newSatVar = SatVar(prefix + str(nd.getID()))
    if type(nd).__name__ == "Literal":
        newCnf = LiteralNode(nd, newSatVar, newCnf)

    if type(nd).__name__ == "BinOp":
        newCnf = BinOpNode(nd, newSatVar, newCnf, prefix)

    if type(nd).__name__ == "UnOp":
        newCnf = UnOpNode(nd, newSatVar, newCnf, prefix)

    return newSatVar, newCnf
Beispiel #8
0
def transform_rec(node, prefix = ''):
    cnf = Cnf()

    children = node.getChildren()
    if type(node).__name__ == "Variable":
        s = SatVar(prefix+node.getName())
        return s, cnf

    s = SatVar(prefix+ "s" + str(node.getID()))
    if type(node).__name__ == "Literal":
        if (node.getValue()):
            cnf = cnf & s
        else:
            cnf = cnf & ~s
        return s, cnf

    if type(node).__name__ == "BinOp":
        a, cnf1 = transform_rec(node.getChild(0), prefix)
        b, cnf2 = transform_rec(node.getChild(1), prefix)
        cnf = cnf & cnf1 & cnf2
        if (node.getOp() == "&"):
            cnf = cnf & mk_and(s, a, b)
        elif (node.getOp() == "^"):
            cnf = cnf & mk_xor(s, a, b)
        elif (node.getOp() == "|"):
            cnf = cnf & mk_or(s, a, b)
        else:
            raise ValueError("Unrecognized operator " + node.getOp())
        return s, cnf

    if type(node).__name__ == "UnOp":
        a, cnf1 = transform_rec(node.getChild(0), prefix)
        cnf = cnf & cnf1
        if (node.getOp() == "~"):
            cnf = cnf & mk_not(s, a)
        else:
            raise ValueError("Unrecognized operator " + node.getOp())
        return s, cnf