Exemple #1
0
    def test_unsat(self):
        result = CheckSatisfiability(f_unsat, 0.001)
        self.assertEqual(result, None)

        b = Box([x, y, z])
        b_copy = Box([x, y, z])
        result = CheckSatisfiability(f_unsat, 0.001, b)
        self.assertEqual(result, False)
        self.assertEqual(b, b_copy)  # Unchanged
Exemple #2
0
    def test_delta_sat(self):
        result = CheckSatisfiability(f_sat, 0.001)
        self.assertEqual(type(result), Box)

        b = Box([x, y, z])
        result = CheckSatisfiability(f_sat, 0.001, b)
        self.assertEqual(result, True)
        self.assertTrue(b[x].diam() < 0.1)
        self.assertTrue(b[y].diam() < 0.1)
        self.assertTrue(b[z].diam() < 0.1)
Exemple #3
0
def test_dreal_orthogonal_sat():
    """
    See whether a model initializes and can build correctly.
    """

    model = Model("Test Model")
    ssalg = SmallStepAlg()
    dralg = DRealAlg()

    with model.build():
        test.premade_models.find_orthogonal()

    model.gen_output_terms()
    model.run_algebra(ssalg)
    model.run_algebra(dralg)

    print(model_graraphviz_trans(model).source())

    controls = list()

    for v in model.controls:
        controls.append(v.final['dreal_exp'])

    fun = forall(
        controls,
        logical_imply(
            logical_and(model.assumption_term().final['dreal_exp'],
                        model.constraint_term().final['dreal_exp']),
            model.guarantee_term().final['dreal_exp']))

    print(fun)
    result = CheckSatisfiability(fun, 0.01)
    print(result)
Exemple #4
0
def inverterLoopTanh(numInverters, numSolutions="all", a=-5.0):
    epsilon = 1e-14
    start = time.time()
    vs = []
    for i in range(numInverters):
        vs.append(Variable("v" + str(i)))

    allConstraints = []

    # Store rambus oscillator constraints
    for i in range(numInverters):
        allConstraints.append(vs[i] >= -1)
        allConstraints.append(vs[i] <= 1)
        inputInd = i
        outputInd = (i + 1) % numInverters
        allConstraints.append(tanh(a * vs[inputInd]) - vs[outputInd] == 0.0)

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break

        # Store constraints pruning search space so that
        # old hyperrectangles are not considered
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            for i in range(numInverters):
                singleExcludingConstraints.append(vs[i] < solution[i][0])
                singleExcludingConstraints.append(vs[i] > solution[i][1])
            excludingConstraints.append(singleExcludingConstraints)

        # Add all the rambus oscillator constraints
        f_sat = logical_and(*allConstraints)
        # Add constraints so that old hyperrectangles are not considered
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((numInverters, 2))
        for i in range(numInverters):
            hyper[i, :] = [
                result[vs[i]].lb() - 2 * epsilon,
                result[vs[i]].ub() + 2 * epsilon
            ]

        #print ("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))

    end = time.time()
    print("time taken", end - start)
    return allSolutions
Exemple #5
0
def inverterScMosfet(inputVoltage, numSolutions="all"):
    epsilon = 1e-14
    start = time.time()
    Vdd = 1.0
    sn = 3
    sp = 2 * sn

    outputVolt = Variable("outputVolt")
    iP = Variable("iP")
    iN = Variable("iN")

    allConstraints = []
    allConstraints.append(outputVolt >= 0.0)
    allConstraints.append(outputVolt <= Vdd)
    allConstraints.append(-iP - iN == 0)
    allConstraints += mvs_id("n", 0.0, inputVoltage, outputVolt, iN, sn)
    allConstraints += mvs_id("p", Vdd, inputVoltage, outputVolt, iP, sp)

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break

        # Store constraints pruning search space so that
        # old hyperrectangles are not considered
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            singleExcludingConstraints.append(outputVolt < solution[0][0])
            singleExcludingConstraints.append(outputVolt > solution[0][1])
            excludingConstraints.append(singleExcludingConstraints)

        #print ("allConstraints")
        #print (allConstraints)
        f_sat = logical_and(*allConstraints)
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((1, 2))
        hyper[0, :] = [
            result[outputVolt].lb() - 2 * epsilon,
            result[outputVolt].ub() + 2 * epsilon
        ]

        #print ("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))

    end = time.time()
    print("time taken", end - start)
    return allSolutions
Exemple #6
0
def exampleFun(numSolutions="all"):
    start = time.time()
    epsilon = 1e-14
    lenV = 1
    x = Variable('x')

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break
        allConstraints = []
        allConstraints.append(2 * x * asin(cos(0.797) * sin(math.pi / x)) -
                              0.0331 * x >= 2 * math.pi - 2.097)
        allConstraints.append(x >= 3)
        allConstraints.append(x <= 64)
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            singleExcludingConstraints.append(x <= solution[0][0])
            singleExcludingConstraints.append(x >= solution[0][1])
            excludingConstraints.append(singleExcludingConstraints)

        #print ("allConstraints")
        #print (allConstraints)
        #print ("numConstraints", len(allConstraints))
        f_sat = logical_and(*allConstraints)
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((1, 2))
        hyper[0, :] = [
            result[x].lb() - 2 * epsilon, result[x].ub() + 2 * epsilon
        ]

        print("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))
    '''constraints = []
	x = Variable('x')
	#constraints.append(x >= 0.0)
	#constraints.append(x <= 64.0)
	constraints.append(2*math.pi - 2*x*asin(cos(0.797)*sin(math.pi/x)) == 2.097 - 0.0331*x)
	f_sat = logical_and(*constraints)
	result = CheckSatisfiability(f_sat, epsilon)
	print (result)'''
    end = time.time()
    print("time taken", end - start)
Exemple #7
0
def inverterTanh(inputVoltage, a=-5.0, numSolutions="all"):
    epsilon = 1e-14
    start = time.time()

    outputVolt = Variable("outputVolt")

    allConstraints = []
    allConstraints.append(outputVolt >= -1.0)
    allConstraints.append(outputVolt <= 1.0)
    allConstraints.append(tanh(a * inputVoltage) - outputVolt == 0)

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break

        # Store constraints pruning search space so that
        # old hyperrectangles are not considered
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            singleExcludingConstraints.append(outputVolt < solution[0][0])
            singleExcludingConstraints.append(outputVolt > solution[0][1])
            excludingConstraints.append(singleExcludingConstraints)

        #print ("allConstraints")
        #print (allConstraints)
        f_sat = logical_and(*allConstraints)
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((1, 2))
        hyper[0, :] = [
            result[outputVolt].lb() - 2 * epsilon,
            result[outputVolt].ub() + 2 * epsilon
        ]

        #print ("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))

    end = time.time()
    print("time taken", end - start)
    return allSolutions
Exemple #8
0
def test_boolean_if_then():
    """
    Tests whether boolean constraints work. True is '1', false is '0'.
    """

    a = Variable('a', Variable.Int)
    b = Variable('b', Variable.Int)

    fun = logical_and(
        if_then_else(a == False, 20, -20) > 0,
        if_then_else(b == True, 13, -12) > 0)

    result = CheckSatisfiability(fun, 0.01)
    print(result)
Exemple #9
0
def test_dreal_interface_othro():
    """
    Just an empty test to make pytest force a parse check.
    """
    t = Variable('theta', Variable.Real)
    a = Variable('a', Variable.Bool)
    b = Variable('b', Variable.Bool)
    c = Variable('c', Variable.Bool)
    d = Variable('d', Variable.Bool)

    fun = forall(
        [t],
        logical_imply(logical_and(t < 3, t > -3),
                      (((sin(t) * if_then_else(b == True, 1, -1) *
                         if_then_else(a == True, sin(t), cos(t))) +
                        (cos(t) * if_then_else(d == True, 1, -1) *
                         if_then_else(c == True, sin(t), cos(t)))) == 0)))

    result = CheckSatisfiability(fun, 0.01)
    print(result)
    assert False
Exemple #10
0
    def test_minimize_via_forall(self):
        # To minimize f(X) s.t. φ(x), this test encodes
        # the problem into a first-order logic formula.
        #
        #    ∃X. φ(X) ∧ [∀Y φ(Y) ⇒ (f(X) ≤ f(Y))]
        #
        # Here we use f(x) = sin(x)cos(x)
        #             φ(X) = (0 ≤ x) ∧ (x ≤ π)
        def f(x):
            return sin(x) * cos(x)

        def phi(x):
            return logical_and(0 <= x, x <= math.pi)

        problem = logical_and(
            phi(x),
            forall([y], logical_and(logical_imply(phi(y),
                                                  f(x) <= f(y)))))
        result = CheckSatisfiability(problem, 0.01)
        self.assertTrue(result)
        self.assertAlmostEqual(result[x].mid(), math.pi * 3 / 4, places=3)
Exemple #11
0
    def invoke_backend(self, _show):
        """Combine all of the SMT expressions into one expression to sent to dReal
        solver to determine solvability

        :param bool show: If true then the full SMT formula that was created is
                          printed
        :returns: dReal model showing the values for each of the parameters
        """
        formula = logical_and(*self.exprs)
        # Prints the generated formula in full, remove serialize for shortened
        if _show:
            #  nx.draw(self.dg)
            #  plt.show()
            print(formula)
        # Return None if not solvable, returns a dict-like structure giving the
        # range of values for each Variable
        model = CheckSatisfiability(formula, 10)
        if model:
            return model
        else:
            return "No solution found"
from dreal.symbolic import Variable, logical_and, sin, cos
from dreal.api import CheckSatisfiability, Minimize

x = Variable("x")
y = Variable("y")
z = Variable("z")

f_sat = logical_and(0 <= x, x <= 10, 0 <= y, y <= 10, 0 <= z, z <= 10,
                    sin(x) + cos(y) == z)

result = CheckSatisfiability(f_sat, 0.001)
print(result)
Exemple #13
0
def rambusOscillatorTanh(numStages, g_cc=0.5, numSolutions="all", a=-5.0):
    epsilon = 1e-14
    start = time.time()
    g_fwd = 1.0
    lenV = numStages * 2
    vs = []
    vfwds = []
    vccs = []
    for i in range(lenV):
        vs.append(Variable("v" + str(i)))
        vfwds.append(Variable("vfwd" + str(i)))
        vccs.append(Variable("vcc" + str(i)))

    allConstraints = []

    # Store rambus oscillator constraints
    for i in range(lenV):
        allConstraints.append(vs[i] >= -1)
        allConstraints.append(vs[i] <= 1)
        fwdInd = (i - 1) % lenV
        ccInd = (i + lenV // 2) % lenV
        allConstraints.append(vfwds[i] == tanh(a * vs[fwdInd]))
        allConstraints.append(vccs[i] == tanh(a * vs[ccInd]))
        allConstraints.append(g_fwd * vfwds[i] + (-g_fwd - g_cc) * vs[i] +
                              g_cc * vccs[i] == 0)

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break

        # Store constraints pruning search space so that
        # old hyperrectangles are not considered
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            for i in range(lenV):
                singleExcludingConstraints.append(vs[i] < solution[i][0])
                singleExcludingConstraints.append(vs[i] > solution[i][1])
            excludingConstraints.append(singleExcludingConstraints)

        # Add all the rambus oscillator constraints
        f_sat = logical_and(*allConstraints)
        # Add constraints so that old hyperrectangles are not considered
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((lenV, 2))
        for i in range(lenV):
            hyper[i, :] = [
                result[vs[i]].lb() - 2 * epsilon,
                result[vs[i]].ub() + 2 * epsilon
            ]

        #print ("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))

    end = time.time()
    print("time taken", end - start)
    return allSolutions
Exemple #14
0
def schmittTriggerScMosfet(inputVoltage, numSolutions="all"):
    epsilon = 1e-14
    start = time.time()

    lenV = 3
    Vdd = 1.0
    sn = 3
    sp = 2 * sn

    vs = []
    tIs = []
    nIs = []

    for i in range(lenV):
        vs.append(Variable("v" + str(i)))
        nIs.append(Variable("nI" + str(i)))

    for i in range(lenV * 2):
        tIs.append(Variable("tI" + str(i)))

    allConstraints = []
    for i in range(lenV):
        allConstraints.append(vs[i] >= 0.0)
        allConstraints.append(vs[i] <= Vdd)
    allConstraints += mvs_id('n', 0.0, inputVoltage, vs[1], tIs[0], sn)
    allConstraints += mvs_id('n', vs[1], inputVoltage, vs[0], tIs[1], sn)
    allConstraints += mvs_id('n', vs[1], vs[0], Vdd, tIs[2], sn)
    allConstraints += mvs_id('p', Vdd, inputVoltage, vs[2], tIs[3], sp)
    allConstraints += mvs_id('p', vs[2], inputVoltage, vs[0], tIs[4], sp)
    allConstraints += mvs_id('p', vs[2], vs[0], 0.0, tIs[5], sp)
    allConstraints.append(nIs[0] == -tIs[4] - tIs[1])
    allConstraints.append(nIs[1] == -tIs[0] + tIs[1] + tIs[2])
    allConstraints.append(nIs[2] == -tIs[3] + tIs[5] + tIs[4])
    for i in range(lenV):
        allConstraints.append(nIs[i] == 0.0)

    allSolutions = []
    while True:
        if numSolutions != "all" and len(allSolutions) == numSolutions:
            break

        # Store constraints pruning search space so that
        # old hyperrectangles are not considered
        excludingConstraints = []
        for solution in allSolutions:
            singleExcludingConstraints = []
            for i in range(lenV):
                singleExcludingConstraints.append(vs[i] < solution[i][0])
                singleExcludingConstraints.append(vs[i] > solution[i][1])
            excludingConstraints.append(singleExcludingConstraints)

        #print ("allConstraints")
        #print (allConstraints)
        f_sat = logical_and(*allConstraints)
        if len(excludingConstraints) > 0:
            for constraints in excludingConstraints:
                f_sat = logical_and(f_sat, logical_or(*constraints))

        #print ("f_sat")
        #print (f_sat)
        result = CheckSatisfiability(f_sat, epsilon)
        #print (result)
        if result is None:
            break
        hyper = np.zeros((lenV, 2))
        for i in range(lenV):
            hyper[i, :] = [
                result[vs[i]].lb() - 2 * epsilon,
                result[vs[i]].ub() + 2 * epsilon
            ]

        #print ("hyper", hyper)
        allSolutions.append(hyper)

        print("num solutions found", len(allSolutions))

    end = time.time()
    print("time taken", end - start)
    return allSolutions
Exemple #15
0
def test_nested_forall():
    """
    Test whether we can choose parameters for a system, such that there is a
    satisfying solution over an entire range of values. 

    Basically, choose an origin (ox,oy) and the lengths of two arms (l1 & l2)
    so that there is an angle (t1 & t2) for each arm, that allows it to reach
    any point within a circle centered at (25,25) with radius 4.

    We want to make sure that the lengths and origin the tool chooses allows
    for 
    
    >   there should:
    >     exists. l1 in (0,20) , l2 (0,20), ox (-20,20), oy (-20,20) 
    >
    >   such that:
    >     for all. px in (20, 30), py in (20,30)
    >
    >   given assumptions:
    >     sqrt((25 - px)**2 + (25 - py)**2) <= 4
    >
    >   there should:
    >     exists. t1 in (-pi, pi), t2 in (-pi,pi)
    >
    >   with constraints:
    >      t2 > t1
    >
    >   that meets the requirements:
    >         (px == l2*sin(t1) + l2*sin(t2) + ox) 
    >      && (py == l1*cos(t1) + l2*cos(t2) + oy)

    """

    # Parameters
    l1 = Variable('l1', Variable.Real)
    l2 = Variable('l2', Variable.Real)
    ox = Variable('ox', Variable.Real)
    oy = Variable('oy', Variable.Real)

    param_bounds = logical_and(l1 > 0, l1 < 20, l2 > 0, l2 < 20, ox > -20,
                               ox < 20, oy > -20, oy < 20)

    # Independent Variables
    px = Variable('px', Variable.Real)
    py = Variable('py', Variable.Real)

    ivar_bounds = logical_and(px > 20, px < 30, py > 20, py < 30)

    ivar_assum = sqrt((25 - px)**2 + (25 - py)**2) < 4

    # Dependent Variables
    t1 = Variable('t1', Variable.Real)
    t2 = Variable('t2', Variable.Real)

    dvar_bounds = logical_and(t1 >= -3.14, t1 <= 3.14, t2 >= -3.14, t2 <= 3.14,
                              t1 >= t2)

    req = logical_and(px == l1 * sin(t1) + l2 * sin(t2) + ox,
                      py == l1 * cos(t1) + l2 * cos(t2) + oy)

    def exists(vs, fun):
        return logical_not(forall(vs, logical_not(fun)))

    fun = logical_and(
        param_bounds,
        forall([px, py],
               logical_imply(logical_and(ivar_bounds, ivar_assum),
                             exists([t1, t2], logical_and(dvar_bounds, req)))))

    result = CheckSatisfiability(fun, 0.01)
    print(result)
    assert False
Exemple #16
0
def rambusOscillatorLcMosfet(numStages, numSolutions = "all", g_cc = 0.5, Vtp = -0.4, Vtn = 0.4, Vdd = 1.8, Kn = 270*1e-6, Kp = -90*1e-6, Sn = 3.0):
	epsilon = 1e-14
	start = time.time()
	#print ("Vtp", Vtp, "Vtn", Vtn, "Vdd", Vdd, "Kn", Kn, "Kp", Kp, "Sn", Sn)
	g_fwd = 1.0
	lenV = numStages*2
	Sp = 2*Sn

	vs = []
	ifwdNs = []
	ifwdPs = []
	iccNs = []
	iccPs = []
	for i in range(lenV):
		vs.append(Variable("v" + str(i)))
		ifwdNs.append(Variable("ifwdN" + str(i)))
		ifwdPs.append(Variable("ifwdP" + str(i)))
		iccNs.append(Variable("iccN" + str(i)))
		iccPs.append(Variable("iccP" + str(i)))

	allConstraints = []	
	for i in range(lenV):
		allConstraints.append(vs[i] >= 0.0)
		allConstraints.append(vs[i] <= Vdd)
		allConstraints.append(g_fwd*(-ifwdNs[i]-ifwdPs[i]) + g_cc*(-iccNs[i]-iccPs[i]) == 0)
		fwdInd = (i-1)%lenV
		ccInd = (i+lenV//2)%lenV
		fwdConstraints = nFet(Vtn, Vdd, Kn, Sn, 0.0, vs[fwdInd], vs[i], ifwdNs[i])
		fwdConstraints += pFet(Vtp, Vdd, Kp, Sp, Vdd, vs[fwdInd], vs[i], ifwdPs[i])
		ccConstraints = nFet(Vtn, Vdd, Kn, Sn, 0.0, vs[ccInd], vs[i], iccNs[i])
		ccConstraints += pFet(Vtp, Vdd, Kp, Sp, Vdd, vs[ccInd], vs[i], iccPs[i])
		allConstraints += fwdConstraints + ccConstraints

	allSolutions = []
	while True:
		if numSolutions != "all" and len(allSolutions) == numSolutions:
			break
		
		# Store constraints pruning search space so that
		# old hyperrectangles are not considered
		excludingConstraints = []
		for solution in allSolutions:
			singleExcludingConstraints = []
			for i in range(lenV):
				singleExcludingConstraints.append(vs[i] < solution[i][0])
				singleExcludingConstraints.append(vs[i] > solution[i][1])
			excludingConstraints.append(singleExcludingConstraints)
		
		#print ("allConstraints")
		#print (allConstraints)
		f_sat = logical_and(*allConstraints)
		if len(excludingConstraints) > 0:
			for constraints in excludingConstraints:
				f_sat = logical_and(f_sat, logical_or(*constraints))
		
		#print ("f_sat")
		#print (f_sat)
		result = CheckSatisfiability(f_sat, epsilon)
		#print (result)
		if result is None:
			break
		hyper = np.zeros((lenV,2))
		for i in range(lenV):
			hyper[i,:] = [result[vs[i]].lb() - 1000*epsilon, result[vs[i]].ub() + 1000*epsilon]

		#print ("hyper", hyper)
		allSolutions.append(hyper)

		print ("num solutions found", len(allSolutions))


	end = time.time()
	print ("time taken", end - start)
	return allSolutions
Exemple #17
0
def inverterLoopLcMosfet(numInverters, numSolutions = "all", Vtp = -0.4, Vtn = 0.4, Vdd = 1.8, Kn = 270*1e-6, Kp = -90*1e-6, Sn = 3.0):
	epsilon = 1e-14
	start = time.time()
	#print ("Vtp", Vtp, "Vtn", Vtn, "Vdd", Vdd, "Kn", Kn, "Kp", Kp, "Sn", Sn)
	Sp = 2*Sn

	vs = []
	iNs = []
	iPs = []

	for i in range(numInverters):
		vs.append(Variable("v" + str(i)))
		iNs.append(Variable("iN" + str(i)))
		iPs.append(Variable("iP" + str(i)))

	allConstraints = []	
	for i in range(numInverters):
		allConstraints.append(vs[i] >= 0.0)
		allConstraints.append(vs[i] <= Vdd)
		allConstraints.append(-iNs[i]-iPs[i] == 0)
		inputInd = i
		outputInd = (i+1)%numInverters
		allConstraints += nFet(Vtn, Vdd, Kn, Sn, 0.0, vs[inputInd], vs[outputInd], iNs[i])
		allConstraints += pFet(Vtp, Vdd, Kp, Sp, Vdd, vs[inputInd], vs[outputInd], iPs[i])

	allSolutions = []
	while True:
		if numSolutions != "all" and len(allSolutions) == numSolutions:
			break
		
		# Store constraints pruning search space so that
		# old hyperrectangles are not considered
		excludingConstraints = []
		for solution in allSolutions:
			singleExcludingConstraints = []
			for i in range(numInverters):
				singleExcludingConstraints.append(vs[i] < solution[i][0])
				singleExcludingConstraints.append(vs[i] > solution[i][1])
			excludingConstraints.append(singleExcludingConstraints)
		
		#print ("allConstraints")
		#print (allConstraints)
		f_sat = logical_and(*allConstraints)
		if len(excludingConstraints) > 0:
			for constraints in excludingConstraints:
				f_sat = logical_and(f_sat, logical_or(*constraints))
		
		#print ("f_sat")
		#print (f_sat)
		result = CheckSatisfiability(f_sat, epsilon)
		#print (result)
		if result is None:
			break
		hyper = np.zeros((numInverters,2))
		for i in range(numInverters):
			hyper[i,:] = [result[vs[i]].lb() - 1000*epsilon, result[vs[i]].ub() + 1000*epsilon]

		#print ("hyper", hyper)
		allSolutions.append(hyper)

		print ("num solutions found", len(allSolutions))


	end = time.time()
	print ("time taken", end - start)
	return allSolutions
Exemple #18
0
def schmittTriggerLcMosfet(inputVoltage, Vtp = -0.4, Vtn = 0.4, Vdd = 1.8, Kn = 270*1e-6, Kp = -90*1e-6, Sn = 3.0, numSolutions = "all"):
	epsilon = 1e-14
	start = time.time()
	#print ("Vtp", Vtp, "Vtn", Vtn, "Vdd", Vdd, "Kn", Kn, "Kp", Kp, "Sn", Sn)
	Sp = Sn *2.0

	lenV = 3

	vs = []
	tIs = []
	nIs = []

	for i in range(lenV):
		vs.append(Variable("v" + str(i)))
		nIs.append(Variable("nI" + str(i)))
	
	for i in range(lenV*2):
		tIs.append(Variable("tI" + str(i)))

	allConstraints = []	
	for i in range(lenV):
		allConstraints.append(vs[i] >= 0.0)
		allConstraints.append(vs[i] <= 1.8)
	allConstraints += nFetLeak(Vtn, Vdd, Kn, Sn, 0.0, inputVoltage, vs[1], tIs[0])
	allConstraints += nFetLeak(Vtn, Vdd, Kn, Sn, vs[1], inputVoltage, vs[0], tIs[1])
	allConstraints += nFetLeak(Vtn, Vdd, Kn, Sn, vs[1], vs[0], Vdd, tIs[2])
	allConstraints += pFetLeak(Vtp, Vdd, Kp, Sp, Vdd, inputVoltage, vs[2], tIs[3])
	allConstraints += pFetLeak(Vtp, Vdd, Kp, Sp, vs[2], inputVoltage, vs[0], tIs[4])
	allConstraints += pFetLeak(Vtp, Vdd, Kp, Sp, vs[2], vs[0], 0.0, tIs[5])
	allConstraints.append(nIs[0] == -tIs[4] - tIs[1])
	allConstraints.append(nIs[1] == -tIs[0] + tIs[1] + tIs[2])
	allConstraints.append(nIs[2] == -tIs[3] + tIs[5] + tIs[4])
	for i in range(lenV):
		allConstraints.append(nIs[i] == 0.0)

	allSolutions = []
	while True:
		if numSolutions != "all" and len(allSolutions) == numSolutions:
			break
		
		# Store constraints pruning search space so that
		# old hyperrectangles are not considered
		excludingConstraints = []
		for solution in allSolutions:
			singleExcludingConstraints = []
			for i in range(lenV):
				singleExcludingConstraints.append(vs[i] < solution[i][0])
				singleExcludingConstraints.append(vs[i] > solution[i][1])
			excludingConstraints.append(singleExcludingConstraints)
		
		#print ("allConstraints")
		#print (allConstraints)
		#print ("numConstraints", len(allConstraints))

		f_sat = logical_and(*allConstraints)
		if len(excludingConstraints) > 0:
			for constraints in excludingConstraints:
				f_sat = logical_and(f_sat, logical_or(*constraints))
		
		#print ("f_sat")
		#print (f_sat)
		result = CheckSatisfiability(f_sat, epsilon)
		#print (result)
		if result is None:
			break
		hyper = np.zeros((lenV,2))
		for i in range(lenV):
			hyper[i,:] = [result[vs[i]].lb() - 1000*epsilon, result[vs[i]].ub() + 1000*epsilon]

		#print ("hyper", hyper)
		allSolutions.append(hyper)

		print ("num solutions found", len(allSolutions))


	end = time.time()
	print ("time taken", end - start)
	return allSolutions