def solve(self, filename="", verbose=True, options=None): """ Function to solve query represented by this network Arguments: filename: (string) path to redirect output to verbose: (bool) whether to print out solution after solve finishes options: (MarabouCore.Options) object for specifying Marabou options Returns: vals: (dict: int->float) empty if UNSAT, else SATisfying solution stats: (Statistics) a Statistics object as defined in Marabou, it has multiple methods that provide information related to how an input query was solved. """ ipq = self.getMarabouQuery() if options == None: options = MarabouCore.Options() vals, stats = MarabouCore.solve(ipq, options, filename) if verbose: if stats.hasTimedOut(): print("TO") elif len(vals) == 0: print("unsat") else: print("sat") for j in range(len(self.inputVars)): for i in range(self.inputVars[j].size): print("input {} = {}".format( i, vals[self.inputVars[j].item(i)])) for i in range(self.outputVars.size): print("output {} = {}".format( i, vals[self.outputVars.item(i)])) return [vals, stats]
def test_dump_query(): """ This function tests that MarabouCore.solve can be called with all arguments and checks that a SAT query is solved correctly. This also tests the InputQuery dump() method as well as bound tightening during solving. """ ipq = define_ipq(3.0) # An upper bound for variable 2 was not given, so Marabou uses float max, which # is much larger than LARGE assert ipq.getUpperBound(2) > LARGE # Solve vals, stats = MarabouCore.solve(ipq, OPT, "") # Test dump ipq.dump() # Marabou should return SAT values, and the dictionary of values should # satisfy all upper and lower bounds assert not stats.hasTimedOut() assert len(vals) > 0 for var in vals: assert vals[var] >= ipq.getLowerBound(var) assert vals[var] <= ipq.getUpperBound(var) # Marabou should find tighter bounds than LARGE after bound propagation, including # for variable 2, where no upper bound was explicitly given assert ipq.getUpperBound(1) < LARGE assert ipq.getLowerBound(2) > -LARGE assert ipq.getUpperBound(2) < LARGE
def solve(self, filename="", verbose=True, options=None): """Function to solve query represented by this network Args: filename (string): Path for redirecting output verbose (bool): If true, print out solution after solve finishes options (:class:`~maraboupy.MarabouCore.Options`): Object for specifying Marabou options, defaults to None Returns: (tuple): tuple containing: - exitCode (str): A string representing the exit code (sat/unsat/TIMEOUT/ERROR/UNKNOWN/QUIT_REQUESTED). - vals (Dict[int, float]): Empty dictionary if UNSAT, otherwise a dictionary of SATisfying values for variables - stats (:class:`~maraboupy.MarabouCore.Statistics`): A Statistics object to how Marabou performed """ ipq = self.getMarabouQuery() if options == None: options = MarabouCore.Options() exitCode, vals, stats = MarabouCore.solve(ipq, options, str(filename)) if verbose: print(exitCode) if exitCode == "sat": for j in range(len(self.inputVars)): for i in range(self.inputVars[j].size): print("input {} = {}".format( i, vals[self.inputVars[j].item(i)])) for j in range(len(self.outputVars)): for i in range(self.outputVars[j].size): print("output {} = {}".format( i, vals[self.outputVars[j].item(i)])) return [exitCode, vals, stats]
def check_sat(self, output_filename="", timeout=0, vars_of_interest=[], verbose=True, dnc=True): # todo: redirect output to cwd/maraboulogs/ if (not dnc) or (self.n_worker == 1): options = Marabou.createOptions(timeoutInSeconds=timeout) else: # dnc options = Marabou.createOptions(timeoutInSeconds=timeout, dnc=True, verbosity=0, initialDivides=2, initialTimeout=120, numWorkers=self.n_worker) # options = Marabou.createOptions(timeoutInSeconds=timeout, dnc=True, verbosity=0, # initialDivides=2, initialTimeout=120, numWorkers=self.n_worker, # biasStrategy="estimate", focusLayer=1000, lookAheadPreprocessing=True) MarabouCore.saveQuery(self.ipq, "query_dump") vals, stats = MarabouCore.solve(self.ipq, options, output_filename) self.convert_sat_vals_to_mc_vars(vals) if verbose: self.print_results(vals, stats, vars_of_interest=vars_of_interest) if stats.hasTimedOut(): return Result.TIMEOUT, self.vals_with_mc_vars, stats elif len(vals) == 0: return Result.UNSAT, self.vals_with_mc_vars, stats else: # len(vals) /== 0 return Result.SAT, self.vals_with_mc_vars, stats
def boundEqConflict(): ''' Simple presecion exmaple. Only two nodes that are conncted with ReLU, and an equation that asks if the ReLU output is very small negative :return: ''' network = MarabouCore.InputQuery() network.setNumberOfVariables(2) network.setLowerBound(0, -5) network.setUpperBound(0, 5) network.setLowerBound(1, 0) network.setUpperBound(1, 5) MarabouCore.addReluConstraint(network, 0, 1) eq = MarabouCore.Equation(MarabouCore.Equation.LE) eq.addAddend(1, 1) eq.setScalar(-10**-4) # -10 ** -4 works network.addEquation(eq) verbose = 2 vars1, stats1 = MarabouCore.solve(network, "", 0, verbose) if len(vars1) > 0: print("SAT") print(vars1) return False else: print("UNSAT") return True
def loadQuery(self, filename="", verbose=True, timeout=0): """ Function to solve query represented by this network Arguments: filename: (string) path to redirect output to verbose: (bool) whether to print out solution Returns: vals: (dict: int->float) empty if UNSAT, else SATisfying solution stats: (Statistics) a Statistics object as defined in Marabou, it has multiple methods that provide information related to how an input query was solved. """ #ipq = self.getMarabouQuery() ipq = MarabouCore.loadQuery(filename) vals, stats = MarabouCore.solve(ipq, filename, timeout=0) if verbose: if stats.hasTimedOut(): print("TIMEOUT") elif len(vals) == 0: print("UNSAT") else: print("SAT") for i in range(self.inputVars.size): print("input {} = {}".format(i, vals[self.inputVars.item(i)])) for i in range(self.outputVars.size): print("output {} = {}".format( i, vals[self.outputVars.item(i)])) return [vals, stats]
def solve(self, filename="", verbose=True, options=None): """Function to solve query represented by this network Args: filename (string): Path for redirecting output verbose (bool): If true, print out solution after solve finishes options (:class:`~maraboupy.MarabouCore.Options`): Object for specifying Marabou options, defaults to None Returns: (tuple): tuple containing: - vals (Dict[int, float]): Empty dictionary if UNSAT, otherwise a dictionary of SATisfying values for variables - stats (:class:`~maraboupy.MarabouCore.Statistics`): A Statistics object to how Marabou performed """ ipq = self.getMarabouQuery() if options == None: options = MarabouCore.Options() vals, stats = MarabouCore.solve(ipq, options, filename) if verbose: if stats.hasTimedOut(): print("TO") elif len(vals) == 0: print("unsat") else: print("sat") for j in range(len(self.inputVars)): for i in range(self.inputVars[j].size): print("input {} = {}".format( i, vals[self.inputVars[j].item(i)])) for i in range(self.outputVars.size): print("output {} = {}".format( i, vals[self.outputVars.item(i)])) return [vals, stats]
def evaluateWithMarabou(self, inputValues, filename="evaluateWithMarabou.log", timeout=0): """ Function to evaluate network at a given point using Marabou as solver Arguments: inputValues: list of (np arrays) representing input to network filename: (string) path to redirect output Returns: outputValues: (np array) representing output of network """ inputVars = self.inputVars # list of numpy arrays outputVars = self.outputVars inputDict = dict() inputVarList = np.concatenate(inputVars, axis=-1).ravel() inputValList = np.concatenate(inputValues).ravel() assignList = zip(inputVarList, inputValList) for x in assignList: inputDict[x[0]] = x[1] ipq = self.getMarabouQuery() for k in inputDict: ipq.setLowerBound(k, inputDict[k]) ipq.setUpperBound(k, inputDict[k]) outputDict = MarabouCore.solve(ipq, filename, timeout) outputValues = outputVars.reshape(-1).astype(np.float64) for i in range(len(outputValues)): outputValues[i] = (outputDict[0])[outputValues[i]] outputValues = outputValues.reshape(outputVars.shape) return outputValues
def marabou_solve_negate_eq(query): vars1, stats1 = MarabouCore.solve(query, "", 0) if len(vars1) > 0: print("SAT") print(vars1) return False else: print("UNSAT") return True
def test_solve_partial_arguments(): """ This function tests that MarabouCore.solve can be called with partial arguments, and checks that an UNSAT query is solved correctly. """ ipq = define_ipq(-2.0) # Test partial arguments to solve vals, stats = MarabouCore.solve(ipq, OPT) # Assert that Marabou returned UNSAT assert not stats.hasTimedOut() assert len(vals) == 0
def evaluateWithMarabou(self, inputValues, filename="evaluateWithMarabou.log", options=None): """Function to evaluate network at a given point using Marabou as solver Args: inputValues (list of np arrays): Inputs to evaluate filename (str): Path to redirect output if using Marabou solver, defaults to "evaluateWithMarabou.log" options (:class:`~maraboupy.MarabouCore.Options`): Object for specifying Marabou options, defaults to None Returns: (list of np arrays): Values representing the outputs of the network or None if system is UNSAT """ # Make sure inputValues is a list of np arrays and not list of lists inputValues = [np.array(inVal) for inVal in inputValues] inputVars = self.inputVars # list of numpy arrays outputVars = self.outputVars # list of numpy arrays inputDict = dict() inputVarList = np.concatenate([inVar.flatten() for inVar in inputVars], axis=-1).flatten() inputValList = np.concatenate( [inVal.flatten() for inVal in inputValues]).flatten() assignList = zip(inputVarList, inputValList) for x in assignList: inputDict[x[0]] = x[1] ipq = self.getMarabouQuery() for k in inputDict: ipq.setLowerBound(k, inputDict[k]) ipq.setUpperBound(k, inputDict[k]) if options == None: options = MarabouCore.Options() exitCode, outputDict, _ = MarabouCore.solve(ipq, options, str(filename)) # When the query is UNSAT an empty dictionary is returned if outputDict == {}: return None outputValues = [ outVars.reshape(-1).astype(np.float64) for outVars in outputVars ] for i in range(len(outputValues)): for j in range(len(outputValues[i])): outputValues[i][j] = outputDict[outputValues[i][j]] outputValues[i] = outputValues[i].reshape(outputVars[i].shape) return outputValues
def test_statistics(): """ Test that a query generated from Maraboupy can be saved and loaded correctly and return sat """ ipq = MarabouCore.InputQuery() ipq.setNumberOfVariables(1) ipq.setLowerBound(0, -1) ipq.setUpperBound(0, 1) opt = createOptions(verbosity = 0) # Turn off printing exitCode, vals, stats = MarabouCore.solve(ipq, opt, "") assert(stats.getUnsignedAttribute(MarabouCore.StatisticsUnsignedAttribute.NUM_SPLITS) == 0) assert(stats.getLongAttribute(MarabouCore.StatisticsLongAttribute.NUM_MAIN_LOOP_ITERATIONS) == 2) assert(stats.getDoubleAttribute(MarabouCore.StatisticsDoubleAttribute.MAX_DEGRADATION) == 0)
def marabou_solve_negate_eq(query, debug=False): ''' Run marabou solver :param query: query to execute :param debug: if True printing all of the query equations :return: True if UNSAT (no valid assignment), False otherwise ''' # if debug: # for eq in query.getEquations(): # eq.dump() vars1, stats1 = MarabouCore.solve(query, "", 0) if len(vars1) > 0: print("SAT") print(vars1) return False else: print("UNSAT") return True
def solve(self, filename="", verbose=True, options=None): """ Function to solve query represented by this network Arguments: filename: (string) path to redirect output to verbose: (bool) whether to print out solution after solve finishes timeout: (int) time in seconds when Marabou will time out verbosity: (int) determines how much Marabou prints during solving 0: print out minimal information 1: print out statistics only in the beginning and the end 2: print out statistics during solving Returns: vals: (dict: int->float) empty if UNSAT, else SATisfying solution stats: (Statistics) a Statistics object as defined in Marabou, it has multiple methods that provide information related to how an input query was solved. """ ipq = self.getMarabouQuery() if options == None: options = MarabouCore.Options() vals, stats = MarabouCore.solve(ipq, options, filename) if verbose: if stats.hasTimedOut(): print("TO") elif len(vals) == 0: print("UNSAT") else: print("SAT") for inputVarArray in self.inputVars: for inputVar in inputVarArray.flatten(): print("input {} = {}".format(inputVar, vals[inputVar])) # print("input var {} input {} = {}".format(i, self.inputVars[j][0][i],vals[self.inputVars[j].item(i)])) # for j in range(len(self.inputVars)): # for i in range(self.inputVars[j].size): # print("input {} = {}".format(i, vals[self.inputVars[j].item(i)])) # print("input var {} input {} = {}".format(i, self.inputVars[j][0][i],vals[self.inputVars[j].item(i)])) for i in range(self.outputVars.size): print("output {} = {}".format( i, vals[self.outputVars.item(i)])) return [vals, stats]
def evaluateWithMarabou(self, inputValues, filename="evaluateWithMarabou.log", options=None): """ Function to evaluate network at a given point using Marabou as solver Arguments: inputValues: list of (np arrays) representing input to network filename: (string) path to redirect output options: (MarabouCore.Options) object for specifying Marabou options Returns: outputValues: (np array) representing output of network """ # Make sure inputValues is a list of np arrays and not list of lists inputValues = [np.array(inVal) for inVal in inputValues] inputVars = self.inputVars # list of numpy arrays outputVars = self.outputVars inputDict = dict() inputVarList = np.concatenate([inVar.flatten() for inVar in inputVars], axis=-1).flatten() inputValList = np.concatenate( [inVal.flatten() for inVal in inputValues]).flatten() assignList = zip(inputVarList, inputValList) for x in assignList: inputDict[x[0]] = x[1] ipq = self.getMarabouQuery() for k in inputDict: ipq.setLowerBound(k, inputDict[k]) ipq.setUpperBound(k, inputDict[k]) if options == None: options = MarabouCore.Options() outputDict, _ = MarabouCore.solve(ipq, options, filename) outputValues = outputVars.reshape(-1).astype(np.float64) for i in range(len(outputValues)): outputValues[i] = outputDict[outputValues[i]] outputValues = outputValues.reshape(outputVars.shape) return outputValues
def solve(self, filename="", timeout=0): """ Function to solve query represented by this network Arguments: filename: (string) path to redirect output to Returns: vals: (dict: int->float) empty if UNSAT, else the satisfying assignment to the input and output variables stats: (Statistics) the Statistics object as defined in Marabou """ options = createOptions(timeoutInSeconds=timeout) vals, stats = MarabouCore.solve(self.ipq, options, filename) assignment = [] if len(vals) > 0: for i in range(self.ipq.getNumInputVariables()): assignment.append("input {} = {}".format( i, vals[self.ipq.inputVariableByIndex(i)])) for i in range(self.ipq.getNumOutputVariables()): assignment.append("Output {} = {}".format( i, vals[self.ipq.outputVariableByIndex(i)])) return [assignment, stats]
def improve_beta(eq, more_is_better): ''' Run the equation on marabou until it is satisfied. If not satisfied taking the value from the index and using it as a s scalar using self.network to verify :param eq: Marabou equation of the form: +-1.000xINDEX >= SCALAR :param more_is_better: If true then adding epsilon on every fail, otherwise substracting :return: a scalar that satisfies the equation ''' proved = False assert len(eq.getAddends()) == 1 idx = eq.getAddends()[0].getVariable() beta = eq.getScalar() while not proved: eq.setScalar(beta) self.network.addEquation(eq) # print("{}: start improve query".format(str(datetime.now()).split(".")[0]), flush=True) vars1, stats1 = MarabouCore.solve(self.network, "", MARABOU_TIMEOUT, 0) # print("{}: finish improve query".format(str(datetime.now()).split(".")[0]), flush=True) if stats1.hasTimedOut(): print("Marabou has timed out") raise TimeoutError() # vars1, stats1 = MarabouCore.solve(self.network, "", 120, 0) if len(vars1) > 0: proved = False if more_is_better: beta = vars1[idx] + SMALL else: beta = vars1[idx] - SMALL # print("proof fail, trying with beta: {}".format(beta)) else: # print("UNSAT") proved = True # print("proof worked, with beta: {}".format(beta)) # self.network.dump() # eq.dump() # beta = beta self.network.removeEquation(eq) return beta
def unfold_sum_rnn(n_iterations, xlim=(-1, 1), ylim=(-1, 1)): i = 0 # index for variable number inputQuery = MarabouCore.InputQuery() num_variables = n_iterations # the x input s_first_index = num_variables num_variables += n_iterations * 2 # for each temporal state (2 because of the ReLu) y_index = num_variables num_variables += 1 # for y inputQuery.setNumberOfVariables(num_variables) for _ in range(n_iterations): inputQuery.setLowerBound(i, xlim[0]) inputQuery.setUpperBound(i, xlim[1]) i += 1 add_rnn_cell_bounds(inputQuery, n_iterations, s_first_index, large) # add s_i # output inputQuery.setLowerBound(y_index, ylim[0]) inputQuery.setUpperBound(y_index, ylim[1]) add_hidden_state_equations(inputQuery, s_first_index, 1, 1, n_iterations) # y - skf = 0 output_equation = MarabouCore.Equation() output_equation.addAddend(1, y_index) output_equation.addAddend(-1, y_index - 1) output_equation.setScalar(0) inputQuery.addEquation(output_equation) vars1, stats1 = MarabouCore.solve(inputQuery, "", 0) if len(vars1) > 0: print("SAT") print(vars1) else: print("UNSAT")
def marabou_solve_negate_eq(query, debug=False, print_vars=False, return_vars=False): ''' Run marabou solver :param query: query to execute :param debug: if True printing all of the query equations :return: True if UNSAT (no valid assignment), False otherwise ''' verbose = 0 # if debug: # query.dump() # print("{}: start query".format(str(datetime.now()).split(".")[0]), flush=True) vars1, stats1 = MarabouCore.solve(query, "", MARABOU_TIMEOUT, verbose) # print("{}: finish query".format(str(datetime.now()).split(".")[0]), flush=True) if stats1.hasTimedOut(): print("Marabou has timed out") raise TimeoutError() if len(vars1) > 0: if print_vars: print("SAT") # print(vars1) # query.dump() # exit(1) res = False else: # print("UNSAT") res = True if return_vars: # if len(vars1) > 0: # print(vars1) return res, vars1 else: return res
def test_solve_partial_arguments(): network = define_network() MarabouCore.solve(network)
cur_equation = MarabouCore.Equation() cur_equation.addAddend(input_weight, k) # xk cur_equation.addAddend(hidden_weight, variables_first_index + (2 * k) - 1) # s(k-1)f cur_equation.addAddend(-1, variables_first_index + (2 * k)) # skb cur_equation.setScalar(0) inputQuery.addEquation(cur_equation) # ReLu's for k in range(variables_first_index, variables_first_index + 2 * num_iterations, 2): MarabouCore.addReluConstraint(inputQuery, k, k + 1) add_hidden_state_equations(inputQuery, s_first_index, 1, 1, num_iterations) add_hidden_state_equations(inputQuery, z_first_index, 1, -1, num_iterations) # y - skf - zkf = 0 output_equation = MarabouCore.Equation() output_equation.addAddend(1, y_index) output_equation.addAddend(-1, z_first_index - 1) output_equation.addAddend(-1, y_index - 1) output_equation.setScalar(0) inputQuery.addEquation(output_equation) vars1, stats1 = MarabouCore.solve(inputQuery, "", 0) if len(vars1) > 0: print("SAT") print(vars1) else: print("UNSAT")
equation1 = MarabouCore.Equation() equation1.addAddend(1, 0) equation1.addAddend(-1, 1) equation1.setScalar(0) inputQuery.addEquation(equation1) equation2 = MarabouCore.Equation() equation2.addAddend(1, 0) equation2.addAddend(1, 3) equation2.setScalar(0) inputQuery.addEquation(equation2) equation3 = MarabouCore.Equation() equation3.addAddend(1, 2) equation3.addAddend(1, 4) equation3.addAddend(-1, 5) equation3.setScalar(0) inputQuery.addEquation(equation3) MarabouCore.addReluConstraint(inputQuery, 1, 2) MarabouCore.addReluConstraint(inputQuery, 3, 4) options = createOptions() vars1, stats1 = MarabouCore.solve(inputQuery, options, "") if len(vars1) > 0: print("SAT") print(vars1) else: print("UNSAT")
equation1.addAddend(-1, 1) equation1.setScalar(0) inputQuery.addEquation(equation1) equation2 = MarabouCore.Equation() equation2.addAddend(1, 0) equation2.addAddend(1, 3) equation2.setScalar(0) inputQuery.addEquation(equation2) equation3 = MarabouCore.Equation() equation3.addAddend(1, 2) equation3.addAddend(1, 4) equation3.addAddend(-1, 5) equation3.setScalar(0) inputQuery.addEquation(equation3) # %% # Add Relu constraints MarabouCore.addReluConstraint(inputQuery, 1, 2) MarabouCore.addReluConstraint(inputQuery, 3, 4) # %% # Run Marabou to solve the query # This should return "sat" options = createOptions() exitCode, vars, stats = MarabouCore.solve(inputQuery, options, "") print(exitCode) if exitCode == "sat": print(vars)
def test_solve_partial_arguments(): network = define_network() options = createOptions() MarabouCore.solve(network, options)
def test_dump_query(): network = define_network() options = createOptions() MarabouCore.solve(network, options, "") network.dump()
def test_dump_query(): network = define_network() MarabouCore.solve(network, "", 0, 0) network.dump()