def test_sample_instantiation(self): # Check that values have not been instantiated sampler = LazyEmbeddingComposite(MockSampler()) self.assertIsNone(sampler.embedding) self.assertIsNone(sampler.nodelist) self.assertIsNone(sampler.edgelist) self.assertIsNone(sampler.adjacency) self.assertIsNone(sampler.parameters) self.assertIsNone(sampler.properties) # Set up BQM and sample csp = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp.add_constraint(and_gate(['a', 'b', 'c'])) bqm = dbc.stitch(csp) sampler.sample(bqm) # Check that values have been populated self.assertIsNotNone(sampler.embedding) self.assertEqual(sampler.nodelist, ['a', 'b', 'c']) self.assertEqual(sampler.edgelist, [('a', 'b'), ('a', 'c'), ('b', 'c')]) self.assertEqual(sampler.adjacency, { 'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'} }) self.assertIsNotNone(sampler.parameters) self.assertIsNotNone(sampler.properties)
def circuit(nbit, vartype=dimod.BINARY): num_multiplier_bits = num_multiplicand_bits = nbit csp = ConstraintSatisfactionProblem(vartype) a = {i: 'a%d' % i for i in range(nbit)} b = {j: 'b%d' % j for j in range(nbit)} p = {k: 'p%d' % k for k in range(nbit * 2)} AND = defaultdict( dict ) # the output of the AND gate associated with ai, bj is stored in AND[i][j] SUM = defaultdict( dict ) # the sum of the ADDER gate associated with ai, bj is stored in SUM[i][j] CARRY = defaultdict(dict) csp.add_constraint(operator.truth, ['a0']) #setting the and gates for i in range(1, nbit - 1): for j in range(1, nbit - 1): ai = a[i] bj = b[j] andij = AND[i][j] = 'and%s,%s' % (i, j) gate = and_gate([ai, bj, andij], vartype=vartype, name='AND(%s, %s) = %s' % (ai, bj, andij)) csp.add_constraint(gate) AND[i][j] = 'and%s,%s' % (i, j) SUM[i][j] = 'sum%d,%d' % (i, j) CARRY[i][j] = 'carry%d,%d' % (i, j) for col in range(0, nbit * 2): """" a1,b1 = 0 a2,b2 = 1 and(a1,b1) = 2 and(a1,b2), and(a2,b1) = 3 and(a2,b2) = 4 sum(3,3) = 5 sum(4,4) = 6 """ #half adder # 1st column # half adder a1 and b1 gate = halfadder_gate([col, b[1], p[1], CARRY[1][1]], vartype=vartype) csp.add_constraint(gate) # # 2nd column # # half adder and(a1,b1) and p2 # gate = halfadder_gate([a[2], AND[1][1], SUM[1][2], CARRY[1][2]], vartype=vartype) # csp.add_constraint(gate) # #full adder # # fulladder of the sum[1][2], carry[0][0] and b2 # gate = fulladder_gate([SUM[2][2], CARRY[0][0], b[2], p[2], CARRY[2][1]], vartype=vartype) # csp.add_constraint(gate) # # 3rd column # # full adder not(and[2][1]), and[1][2] and carry[1][2] # gate = fulladder_gate([not(AND[2][1]), AND[1][2], CARRY[1][2], SUM[3][3], CARRY[3][3]], vartype=vartype) # csp.add_constraint(gate) # # half adder # gate = halfadder_gate([not(SUM[3][3]), not(CARRY[2][1]), not(p[3]), CARRY[5][2]], vartype=vartype) # csp.add_constraint(gate) # # 4th column # # full adder and(p2,q2), q1 and not(p2,q1) # gate = fulladder_gate([AND[2][2], b[1], not(AND[2][1]), SUM[3][0], CARRY[3][0]], vartype=vartype) # csp.add_constraint(gate) # # full adder a1, sum, carry # gate = fulladder_gate([a[1], SUM[3][0], CARRY[3][3], SUM[][], CARRY[][]], vartype=vartype) # csp.add_constraint(gate) # # half adder sum and not(carry) # gate = halfadder_gate([SUM[][], not(CARRY[4][4]), p[4], CARRY[][]], vartype=vartype) # csp.add_constraint(gate) # #5th column # #full adder a2,b2, carry # #full adder sum, carry, carry # #6th column # #half adder carry not, carry not return csp
def multiplication_circuit(nbit, vartype=dimod.BINARY): """Multiplication circuit constraint satisfaction problem. A constraint satisfaction problem that represents the binary multiplication :math:`ab=p`, where the multiplicands are binary variables of length `nbit`; for example, :math:`2^ma_{nbit} + ... + 4a_2 + 2a_1 + a0`. The square below shows a graphic representation of the circuit:: ________________________________________________________________________________ | and20 and10 and00 | | | | | | | and21 add11──and11 add01──and01 | | | |┌───────────┘|┌───────────┘| | | | and22 add12──and12 add02──and02 | | | | |┌───────────┘|┌───────────┘| | | | | add13─────────add03 | | | | | ┌───────────┘| | | | | | | p5 p4 p3 p2 p1 p0 | -------------------------------------------------------------------------------- Args: nbit (int): Number of bits in the multiplicands. vartype (Vartype, optional, default='BINARY'): Variable type. Accepted input values: * Vartype.SPIN, 'SPIN', {-1, 1} * Vartype.BINARY, 'BINARY', {0, 1} Returns: CSP (:obj:`.ConstraintSatisfactionProblem`): CSP that is satisfied when variables :math:`a,b,p` are assigned values that correctly solve binary multiplication :math:`ab=p`. Examples: This example creates a multiplication circuit CSP that multiplies two 3-bit numbers, which is then formulated as a binary quadratic model (BQM). It fixes the multiplacands as :math:`a=5, b=3` (:math:`101` and :math:`011`) and uses a simulated annealing sampler to find the product, :math:`p=15` (:math:`001111`). >>> from dwavebinarycsp.factories.csp.circuits import multiplication_circuit >>> import neal >>> csp = multiplication_circuit(3) >>> bqm = dwavebinarycsp.stitch(csp) >>> bqm.fix_variable('a0', 1); bqm.fix_variable('a1', 0); bqm.fix_variable('a2', 1) >>> bqm.fix_variable('b0', 1); bqm.fix_variable('b1', 1); bqm.fix_variable('b2', 0) >>> sampler = neal.SimulatedAnnealingSampler() >>> response = sampler.sample(bqm) >>> p = next(response.samples(n=1, sorted_by='energy')) >>> print(p['p5'], p['p4'], p['p3'], p['p2'], p['p1'], p['p0']) # doctest: +SKIP 0 0 1 1 1 1 """ if nbit < 1: raise ValueError( "num_multiplier_bits, num_multiplicand_bits must be positive integers" ) num_multiplier_bits = num_multiplicand_bits = nbit # also checks the vartype argument csp = ConstraintSatisfactionProblem(vartype) # throughout, we will use the following convention: # i to refer to the bits of the multiplier # j to refer to the bits of the multiplicand # k to refer to the bits of the product # create the variables corresponding to the input and output wires for the circuit a = {i: 'a%d' % i for i in range(nbit)} b = {j: 'b%d' % j for j in range(nbit)} p = {k: 'p%d' % k for k in range(nbit + nbit)} # we will want to store the internal variables somewhere AND = defaultdict( dict ) # the output of the AND gate associated with ai, bj is stored in AND[i][j] SUM = defaultdict( dict ) # the sum of the ADDER gate associated with ai, bj is stored in SUM[i][j] CARRY = defaultdict( dict ) # the carry of the ADDER gate associated with ai, bj is stored in CARRY[i][j] # we follow a shift adder for i in range(num_multiplier_bits): for j in range(num_multiplicand_bits): ai = a[i] bj = b[j] if i == 0 and j == 0: # in this case there are no inputs from lower bits, so our only input is the AND # gate. And since we only have one bit to add, we don't need an adder, no have a # carry out andij = AND[i][j] = p[0] gate = and_gate([ai, bj, andij], vartype=vartype, name='AND(%s, %s) = %s' % (ai, bj, andij)) csp.add_constraint(gate) continue # we always need an AND gate andij = AND[i][j] = 'and%s,%s' % (i, j) gate = and_gate([ai, bj, andij], vartype=vartype, name='AND(%s, %s) = %s' % (ai, bj, andij)) csp.add_constraint(gate) # the number of inputs will determine the type of adder inputs = [andij] # determine if there is a carry in if i - 1 in CARRY and j in CARRY[i - 1]: inputs.append(CARRY[i - 1][j]) # determine if there is a sum in if i - 1 in SUM and j + 1 in SUM[i - 1]: inputs.append(SUM[i - 1][j + 1]) # ok, add create adders if necessary if len(inputs) == 1: # we don't need an adder and we don't have a carry SUM[i][j] = andij elif len(inputs) == 2: # we need a HALFADDER so we have a sum and a carry if j == 0: sumij = SUM[i][j] = p[i] else: sumij = SUM[i][j] = 'sum%d,%d' % (i, j) carryij = CARRY[i][j] = 'carry%d,%d' % (i, j) name = 'HALFADDER(%s, %s) = %s, %s' % (inputs[0], inputs[1], sumij, carryij) gate = halfadder_gate([inputs[0], inputs[1], sumij, carryij], vartype=vartype, name=name) csp.add_constraint(gate) else: assert len(inputs) == 3, 'unexpected number of inputs' # we need a FULLADDER so we have a sum and a carry if j == 0: sumij = SUM[i][j] = p[i] else: sumij = SUM[i][j] = 'sum%d,%d' % (i, j) carryij = CARRY[i][j] = 'carry%d,%d' % (i, j) name = 'FULLADDER(%s, %s, %s) = %s, %s' % ( inputs[0], inputs[1], inputs[2], sumij, carryij) gate = fulladder_gate( [inputs[0], inputs[1], inputs[2], sumij, carryij], vartype=vartype, name=name) csp.add_constraint(gate) # now we have a final row of full adders for col in range(nbit - 1): inputs = [CARRY[nbit - 1][col], SUM[nbit - 1][col + 1]] if col == 0: sumout = p[nbit + col] carryout = CARRY[nbit][col] = 'carry%d,%d' % (nbit, col) name = 'HALFADDER(%s, %s) = %s, %s' % (inputs[0], inputs[1], sumout, carryout) gate = halfadder_gate([inputs[0], inputs[1], sumout, carryout], vartype=vartype, name=name) csp.add_constraint(gate) continue inputs.append(CARRY[nbit][col - 1]) sumout = p[nbit + col] if col < nbit - 2: carryout = CARRY[nbit][col] = 'carry%d,%d' % (nbit, col) else: carryout = p[2 * nbit - 1] name = 'FULLADDER(%s, %s, %s) = %s, %s' % (inputs[0], inputs[1], inputs[2], sumout, carryout) gate = fulladder_gate( [inputs[0], inputs[1], inputs[2], sumout, carryout], vartype=vartype, name=name) csp.add_constraint(gate) return csp
def multiplication_circuit(nbit, vartype=dimod.BINARY): """todo and20 and10 and00 | | | and21 add11──and11 add01──and01 | |┌───────────┘|┌───────────┘| | and22 add12──and12 add02──and02 | | |┌───────────┘|┌───────────┘| | | add13─────────add03 | | | ┌───────────┘| | | | | p5 p4 p3 p2 p1 p0 """ if nbit < 1: raise ValueError( "num_multiplier_bits, num_multiplicand_bits must be positive integers" ) num_multiplier_bits = num_multiplicand_bits = nbit # also checks the vartype argument csp = ConstraintSatisfactionProblem(vartype) # throughout, we will use the following convention: # i to refer to the bits of the multiplier # j to refer to the bits of the multiplicand # k to refer to the bits of the product # create the variables corresponding to the input and output wires for the circuit a = {i: 'a%d' % i for i in range(nbit)} b = {j: 'b%d' % j for j in range(nbit)} p = {k: 'p%d' % k for k in range(nbit + nbit)} # we will want to store the internal variables somewhere AND = defaultdict( dict ) # the output of the AND gate associated with ai, bj is stored in AND[i][j] SUM = defaultdict( dict ) # the sum of the ADDER gate associated with ai, bj is stored in SUM[i][j] CARRY = defaultdict( dict ) # the carry of the ADDER gate associated with ai, bj is stored in CARRY[i][j] # we follow a shift adder for i in range(num_multiplicand_bits): for j in range(num_multiplier_bits): ai = a[i] bj = b[j] if i == 0 and j == 0: # in this case there are no inputs from lower bits, so our only input is the AND # gate. And since we only have one bit to add, we don't need an adder, no have a # carry out andij = AND[i][j] = p[0] gate = and_gate([ai, bj, andij], vartype=vartype, name='AND(%s, %s) = %s' % (ai, bj, andij)) csp.add_constraint(gate) continue # we always need an AND gate andij = AND[i][j] = 'and%s,%s' % (i, j) gate = and_gate([ai, bj, andij], vartype=vartype, name='AND(%s, %s) = %s' % (ai, bj, andij)) csp.add_constraint(gate) # the number of inputs will determine the type of adder inputs = [andij] # determine if there is a carry in if i - 1 in CARRY and j in CARRY[i - 1]: inputs.append(CARRY[i - 1][j]) # determine if there is a sum in if i - 1 in SUM and j + 1 in SUM[i - 1]: inputs.append(SUM[i - 1][j + 1]) # ok, add create adders if necessary if len(inputs) == 1: # we don't need an adder and we don't have a carry SUM[i][j] = andij elif len(inputs) == 2: # we need a HALFADDER so we have a sum and a carry if j == 0: sumij = SUM[i][j] = p[i] else: sumij = SUM[i][j] = 'sum%d,%d' % (i, j) carryij = CARRY[i][j] = 'carry%d,%d' % (i, j) name = 'HALFADDER(%s, %s) = %s, %s' % (inputs[0], inputs[1], sumij, carryij) gate = halfadder_gate([inputs[0], inputs[1], sumij, carryij], vartype=vartype, name=name) csp.add_constraint(gate) else: assert len(inputs) == 3, 'unexpected number of inputs' # we need a FULLADDER so we have a sum and a carry if j == 0: sumij = SUM[i][j] = p[i] else: sumij = SUM[i][j] = 'sum%d,%d' % (i, j) carryij = CARRY[i][j] = 'carry%d,%d' % (i, j) name = 'FULLADDER(%s, %s, %s) = %s, %s' % ( inputs[0], inputs[1], inputs[2], sumij, carryij) gate = fulladder_gate( [inputs[0], inputs[1], inputs[2], sumij, carryij], vartype=vartype, name=name) csp.add_constraint(gate) # now we have a final row of full adders for col in range(nbit - 1): inputs = [CARRY[nbit - 1][col], SUM[nbit - 1][col + 1]] if col == 0: sumout = p[nbit + col] carryout = CARRY[nbit][col] = 'carry%d,%d' % (nbit, col) name = 'HALFADDER(%s, %s) = %s, %s' % (inputs[0], inputs[1], sumout, carryout) gate = halfadder_gate([inputs[0], inputs[1], sumout, carryout], vartype=vartype, name=name) csp.add_constraint(gate) continue inputs.append(CARRY[nbit][col - 1]) sumout = p[nbit + col] if col < nbit - 2: carryout = CARRY[nbit][col] = 'carry%d,%d' % (nbit, col) else: carryout = p[2 * nbit - 1] name = 'FULLADDER(%s, %s, %s) = %s, %s' % (inputs[0], inputs[1], inputs[2], sumout, carryout) gate = fulladder_gate( [inputs[0], inputs[1], inputs[2], sumout, carryout], vartype=vartype, name=name) csp.add_constraint(gate) return csp
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://docs.ocean.dwavesys.com/en/latest/overview/solving_problems.html ''' -x1 -x2 +2x1x2 lower values for valid states of the NOT gate (e.g., x1=0,x2=1) and higher for invalid states (e.g., x1=0,x2=0). ''' import dwavebinarycsp import dwavebinarycsp.factories.constraint.gates as gates csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(gates.and_gate(['x1', 'x2', 'y1'])) # add an AND gate bqm = dwavebinarycsp.stitch(csp) ''' The members of the two dicts are linear and quadratic coefficients, respectively, the third term is a constant offset associated with the model, and the fourth shows the variable types in this model are binary. ''' print(bqm) # BQM of the AND gate created print('################################################################################') from dimod.reference.samplers import ExactSolver sampler = ExactSolver() response = sampler.sample(bqm) print(response) for datum in response.data(): print(datum) for sample, energy in response.data(fields=['sample', 'energy'], sorted_by='energy'):
from dwave.cloud import Client from dwave.system import DWaveSampler import dwavebinarycsp import dwavebinarycsp.factories.constraint.gates as gates """Simple test file for seeing how a CSP works""" csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(gates.and_gate(['x1', 'x2', 'y1'])) csp.add_constraint(gates.and_gate(['x1', 'x3', 'y1'])) # print(csp.check({'x1': 0})) bqm = dwavebinarycsp.stitch(csp) print(bqm) # client = Client.from_config(token='DEV-32a72b08f81fd9fc8584ab76331bf18aa7913765') # print(client.get_solvers()) # sampler = DWaveSampler(solver={'qpu': True}) # print(sampler.parameters)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://support.dwavesys.com/hc/en-us/community/posts/360016737274-Save-time-Reuse-your-embedding-when-possible import dwavebinarycsp as dbc import dwavebinarycsp.factories.constraint.gates as gates from dwave.system.composites import FixedEmbeddingComposite, EmbeddingComposite from dwave.system.samplers import DWaveSampler # Making two different BQMs (think: energy functions or optimization functions) csp1 = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp1.add_constraint(gates.and_gate(['a', 'b', 'c'])) bqm1 = dbc.stitch(csp1) csp2 = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp2.add_constraint(gates.or_gate(['a', 'b', 'c'])) bqm2 = dbc.stitch(csp2) # Using Embedding Composite sampler = EmbeddingComposite(DWaveSampler()) sampler.sample(bqm1) # Gets a new embedding for bqm1 sampler.sample(bqm2) # Gets a new embedding for bqm2 # Using Fixed Embedding Composite # Note: bqm1 and bqm2 can both be represented by the same graph - triangle graph. embedding = { 'a': [0, 4], 'b': [1], 'c': [5] } # Embedding the triangle graph using QPU indices
or7 = and5 or not6 return(z == or7) csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(logic_circuit, ['a', 'b', 'c', 'd', 'z']) #Multiple Constraints import dwavebinarycsp import dwavebinarycsp.factories.constraint.gates as gates import operator csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(operator.ne, ['b', 'not1']) #add NOT 1 gate csp.add_constraint(gates.or_gate(['b', 'c', 'or2'])) #add OR 2 gate csp.add_constraint(gates.and_gate(['a', 'not1', 'and3'])) # add AND 3 gate csp.add_constraint(gates.or_gate(['d', 'or2', 'or4'])) # add OR 4 gate csp.add_constraint(gates.and_gate(['and3', 'or4', 'and5'])) # add AND 5 gate csp.add_constraint(operator.ne, ['or4', 'not6']) # add NOT 6 gate csp.add_constraint(gates.or_gate(['and5', 'not6', 'z']) # add OR 7 gate # Convert the binary constraint satisfaction problem to a binary quadratic model bqm = dwavebinarycsp.stitch(csp) --------- #The next code sets up the D-Wave sampler --------- from dwave.system.samplers import DWaveSampler
For the full-adder we will use: inputs (a, b, Cin) outputs (s, cOut) For the intermediate variables we will use: (xor1, xor2, and1, and2, or1) However, s and xor2 are the same, and cOut and or1 are the same. See this image for a graphical view of this circuit: https://upload.wikimedia.org/wikipedia/commons/5/57/Fulladder.gif """ csp.add_constraint(gates.xor_gate(['a', 'b', 'xor1'])) # xor(a,b) = xor1 csp.add_constraint(gates.xor_gate(['xor1', 'cIn', 's'])) # xor(xor1,cIn) = s csp.add_constraint(gates.and_gate(['xor1', 'cIn', 'and1'])) # and(xor1,cIn) = and1 csp.add_constraint(gates.and_gate(['a', 'b', 'and2'])) # and(a,b) = and2 csp.add_constraint(gates.or_gate(['and1', 'and2', 'cOut'])) # or(and1,and2) = cOut # This is an example of an assert I used to ensure my constraints above # faithfully reproduced the full-adder I want to implement. # https://docs.ocean.dwavesys.com/projects/binarycsp/en/latest/reference/generated/dwavebinarycsp.ConstraintSatisfactionProblem.check.html assert csp.check({ 'a': 1, 'and1': 0, 'and2': 1, 'b': 1, 'cIn': 0, 'cOut': 1,
gt For the 2 by 2 multiplier we will use: inputs (a0, a1, b0, b1) outputs (c0, c1, c2, c3) For the intermediate variables we will use: (and1, and2, and3, and4, xor1, and5, xor2, and6) However, we will drop some of the intermediate variables because: c0 = and2, c1 = xor1, c2 = xor2, c3 = and6 See this image for a graphical view of this circuit: https://en.wikipedia.org/wiki/Binary_multiplier#/media/File:Binary_multi1.jpg """ csp.add_constraint(gates.and_gate(['a0', 'b1', 'and1' ])) # and(a0, b1) = and1 csp.add_constraint(gates.and_gate(['a0', 'b0', 'c0' ])) # and(a0, b0) = c0 csp.add_constraint(gates.and_gate(['a1', 'b0', 'and3' ])) # and(a1, b0) = and3 csp.add_constraint(gates.and_gate(['a1', 'b1', 'and4' ])) # and(a1, b1) = and4 csp.add_constraint(gates.xor_gate(['and1', 'and3', 'c1' ])) # xor(and1, and3) = c1 csp.add_constraint(gates.and_gate(['and1', 'and3', 'and5' ])) # and(and1, and3) = and5 csp.add_constraint(gates.xor_gate(['and5', 'and4', 'c2' ])) # xor(and5, and4) = c2 csp.add_constraint(gates.and_gate(['and5', 'and4', 'c3' ])) # and(and5, and4) = c3 """ Now that we have defined the gates for our 2 by 2 multiplier, we need to fix the output because we want to factor a number. In this case, we want to factor the number 9, which is 1001 in binary. There are several ways to fix the number, and each way impacts performance and
import dwavebinarycsp import dwavebinarycsp.factories.constraint.gates as gates import operator from dimod.reference.samplers import ExactSolver ## Set up the logic gates, to implement this function: ## (a OR b) AND (NOT a OR c) AND (NOT b OR NOT c) AND (a OR c) csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(operator.ne, ['a', 'na']) # NOT gate csp.add_constraint(operator.ne, ['b', 'nb']) # NOT gate csp.add_constraint(operator.ne, ['c', 'nc']) # NOT gate csp.add_constraint(gates.or_gate(['a', 'b', 'a_or_b'])) # OR gate csp.add_constraint(gates.or_gate(['na', 'c', 'na_or_c'])) # OR gate csp.add_constraint(gates.or_gate(['nb', 'nc', 'nb_or_nc'])) # OR gate csp.add_constraint(gates.or_gate(['a', 'c', 'a_or_c'])) # OR gate csp.add_constraint(gates.and_gate(['a_or_b', 'na_or_c', 'and1'])) # AND gate csp.add_constraint(gates.and_gate(['nb_or_nc', 'a_or_c', 'and2'])) # AND gate csp.add_constraint(gates.and_gate(['and1', 'and2', 'result'])) # AND gate csp.fix_variable('result', 1) # Specify that the result should be one bqm = dwavebinarycsp.stitch(csp) ## Run the solver sampler = ExactSolver() response = sampler.sample(bqm) ## Print all of the results for datum in response.data(['sample', 'energy']): print(datum.sample, datum.energy) def check_result(a, b, c): # Check to make sure a result is valid
## Rather than using a QPU gate-based solution as shown in the QCEngine version, ## this demo implements the same circuit using quantum annealing to find ## the answer, by linking it to the "energy level" of a system. ## In this example, we build the circuit shown in Figure 10-3 in the book, ## and then simply print out all of the energy values. ## Required imports import dwavebinarycsp import dwavebinarycsp.factories.constraint.gates as gates import operator from dimod.reference.samplers import ExactSolver ## Set up the logic gates, exactly as shown in Figure 10-3 in the book. csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(operator.ne, ['b', 'not_b']) csp.add_constraint(gates.or_gate(['a', 'not_b', 'a_or_not_b'])) csp.add_constraint(gates.and_gate(['c', 'a_or_not_b', 'result'])) bqm = dwavebinarycsp.stitch(csp) ## Run the solver sampler = ExactSolver() response = sampler.sample(bqm) ## Interpret the results print('All results: --------------------------------') for datum in response.data(['sample', 'energy']): print(datum.sample, datum.energy)