Esempio n. 1
0
def read_sol(model, sol_filename, symbol_map_filename, suffixes=[".*"]):
    """
    Reads the solution from the SOL file and generates a
    results object with an appropriate symbol map for
    loading it into the given Pyomo model. By default all
    suffixes found in the NL file will be extracted. This
    can be overridden using the suffixes keyword, which
    should be a list of suffix names or regular expressions
    (or None).
    """
    if suffixes is None:
        suffixes = []

    # parse the SOL file
    with ReaderFactory(ResultsFormat.sol) as reader:
        results = reader(sol_filename, suffixes=suffixes)

    # regenerate the symbol_map for this model
    with open(symbol_map_filename, "rb") as f:
        symbol_cuid_pairs = pickle.load(f)
    symbol_map = SymbolMap()
    symbol_map.addSymbols((cuid.find_component(model), symbol)
                          for symbol, cuid in symbol_cuid_pairs)

    # tag the results object with the symbol_map
    results._smap = symbol_map

    return results
Esempio n. 2
0
def read_sol(model, sol_filename, symbol_map_filename, suffixes=[".*"]):
    """
    Reads the solution from the SOL file and generates a
    results object with an appropriate symbol map for
    loading it into the given Pyomo model. By default all
    suffixes found in the NL file will be extracted. This
    can be overridden using the suffixes keyword, which
    should be a list of suffix names or regular expressions
    (or None).
    """
    if suffixes is None:
        suffixes = []

    # parse the SOL file
    with ReaderFactory(ResultsFormat.sol) as reader:
        results = reader(sol_filename, suffixes=suffixes)

    # regenerate the symbol_map for this model
    with open(symbol_map_filename, "rb") as f:
        symbol_cuid_pairs = pickle.load(f)
    symbol_map = SymbolMap()
    symbol_map.addSymbols((cuid.find_component(model), symbol) for symbol, cuid in symbol_cuid_pairs)

    # tag the results object with the symbol_map
    results._smap = symbol_map

    return results
Esempio n. 3
0
 def __init__(self, model=None, logger=None):
     self.variable_label_map = SymbolMap(NumericLabeler('x'))
     self.prefix_expr_list = self._get_default_functions()
     self.variable_list = []
     self.bounds_list = []
     self.expression_list = []
     self.disjunctions_list = []
     self.walker = SMT_visitor(self.variable_label_map)
     self.solver = z3.Solver()
     self.logger = logger
     if model is not None:
         self._process_model(model)
Esempio n. 4
0
 def __init__(self, model=None, logger=None):
     self.variable_label_map = SymbolMap(NumericLabeler('x'))
     self.prefix_expr_list = self._get_default_functions()
     self.variable_list = []
     self.bounds_list = []
     self.expression_list = []
     self.disjunctions_list = []
     self.walker = SMT_visitor(self.variable_label_map)
     self.solver = z3.Solver()
     self.logger = logger
     if model is not None:
         self._process_model(model)
Esempio n. 5
0
class SMTSatSolver(object):
    """
    Satisfiability solver that checks constraint feasibility through use of
    z3 Sat Solver. Object stores expressions and variables in form consistent
    with SMT-LIB standard.
    For documentation on SMT-LIB standard see
    http://smtlib.cs.uiowa.edu/
    """

    def __str__(self):
        """
        Defined string representation of object
        """
        string = ""
        string = string + "Variables:\n"
        for v in self.variable_list:
            string = string + v
        string = string + "Bounds:\n"
        for e in self.bounds_list:
            string = string + e
        string = string + "Expressions:\n"
        for e in self.expression_list:
            string = string + e
        string = string + "Disjunctions:\n"
        for djn in self.disjunctions_list:
            string = string + "Disjunction: " + djn[0] + "\n"
            for disj in djn[1]:
                string = string + "  " + disj[0] + " : " + "\n"
                for c in disj[1]:
                    string = string + "    " + c + "\n"
        return string

    def __init__(self, model=None, logger=None):
        self.variable_label_map = SymbolMap(NumericLabeler('x'))
        self.prefix_expr_list = self._get_default_functions()
        self.variable_list = []
        self.bounds_list = []
        self.expression_list = []
        self.disjunctions_list = []
        self.walker = SMT_visitor(self.variable_label_map)
        self.solver = z3.Solver()
        self.logger = logger
        if model is not None:
            self._process_model(model)

    # Set up functions to be added to beginning of string
    def _get_default_functions(self):
        default = list()
        default.append("(define-fun exp ((x Real)) Real (^ %0.15f x))" % (math.exp(1),))
        return default

    # processes pyomo model into SMT model
    def _process_model(self, model):
        for v in model.component_data_objects(ctype=Var, descend_into=True):
            smtstring = self.add_var(v)
        for c in model.component_data_objects(ctype=Constraint, active=True):
            self.add_expr(c.expr)
        for djn in model.component_data_objects(ctype=Disjunction):
            if djn.active:
                self._process_active_disjunction(djn)
            else:
                self._process_inactive_disjunction(djn)

    # define bound constraints
    def _add_bound(self, var):
        nm = self.variable_label_map.getSymbol(var)
        lb = var.lb
        ub = var.ub
        if lb is not None:
            self.bounds_list.append("(assert (>= " + nm + " " + str(lb) + "))\n")
        if ub is not None:
            self.bounds_list.append("(assert (<= " + nm + " " + str(ub) + "))\n")

    # define variables
    def add_var(self, var):
        label = self.variable_label_map.getSymbol(var)
        domain = var.domain
        if isinstance(domain, RealSet):
            self.variable_list.append("(declare-fun " + label + "() Real)\n")
            self._add_bound(var)
        elif isinstance(domain, IntegerSet):
            self.variable_list.append("(declare-fun " + label + "() Int)\n")
            self._add_bound(var)
        elif isinstance(domain, BooleanSet):
            self.variable_list.append("(declare-fun " + label + "() Int)\n")
            self._add_bound(var)
        else:
            raise NotImplementedError("SMT cannot handle" + str(domain) + "variables")
        return label

    # Defines SMT expression from pyomo expression
    def add_expr(self, expression):
        try:
            smtexpr = self.walker.walk_expression(expression)
            self.expression_list.append("(assert " + smtexpr + ")\n")
        except NotImplementedError as e:
            if self.logger is not None:
                self.logger.warning("Skipping Expression: " + str(e))

    # Computes the SMT Model for the disjunction from the internal class storage
    def _compute_disjunction_string(self, smt_djn):
        djn_string = smt_djn[0]
        for disj in smt_djn[1]:
            cons_string = "true"
            for c in disj[1]:
                cons_string = "(and " + cons_string + " " + c + ")"
            djn_string = djn_string + "(assert (=> ( = 1 " + disj[0] + ") " + cons_string + "))\n"
        return djn_string

    # converts disjunction to internal class storage
    def _process_active_disjunction(self, djn):
        or_expr = "0"
        disjuncts = []
        for disj in djn.disjuncts:
            constraints = []
            iv = disj.indicator_var
            label = self.add_var(iv)
            or_expr = "(+ " + or_expr + " " + label + ")"
            for c in disj.component_data_objects(ctype=Constraint, active=True):
                try:
                    constraints.append(self.walker.walk_expression(c.expr))
                except NotImplementedError as e:
                    if self.logger is not None:
                        self.logger.warning("Skipping Disjunct Expression: " + str(e))
            disjuncts.append((label, constraints))
        if djn.xor:
            or_expr = "(assert (= 1 " + or_expr + "))\n"
        else:
            or_expr = "(assert (>= 1 " + or_expr + "))\n"
        self.disjunctions_list.append((or_expr, disjuncts))

    # processes inactive disjunction indicator vars without constraints
    def _process_inactive_disjunction(self, djn):
        or_expr = "0"
        for disj in djn.disjuncts:
            iv = disj.indicator_var
            label = self.add_var(iv)
            or_expr = "(+ " + or_expr + " " + label + ")"
        if djn.xor:
            or_expr = "(assert (= 1 " + or_expr + "))\n"
        else:
            or_expr = "(assert (>= 1 " + or_expr + "))\n"
        self.expression_list.append(or_expr)

    def get_SMT_string(self):
        prefix_string = ''.join(self.prefix_expr_list)
        variable_string = ''.join(self.variable_list)
        bounds_string = ''.join(self.bounds_list)
        expression_string = ''.join(self.expression_list)
        disjunctions_string = ''.join([self._compute_disjunction_string(d) for d in self.disjunctions_list])
        smtstring = prefix_string + variable_string + bounds_string + expression_string + disjunctions_string
        return smtstring

    def get_var_dict(self):
        labels = [x for x in self.variable_label_map.bySymbol]
        labels.sort()
        vars = [self.variable_label_map.getObject(l) for l in labels]
        return zip(labels, vars)

    # Checks Satisfiability of model
    def check(self):
        self.solver.append(z3.parse_smt2_string(self.get_SMT_string()))
        return self.solver.check()
Esempio n. 6
0
class SMTSatSolver(object):
    """
    Satisfiability solver that checks constraint feasibility through use of
    z3 Sat Solver. Object stores expressions and variables in form consistent
    with SMT-LIB standard.
    For documentation on SMT-LIB standard see
    http://smtlib.cs.uiowa.edu/
    """
    def __str__(self):
        """
        Defined string representation of object
        """
        string = ""
        string = string + "Variables:\n"
        for v in self.variable_list:
            string = string + v
        string = string + "Bounds:\n"
        for e in self.bounds_list:
            string = string + e
        string = string + "Expressions:\n"
        for e in self.expression_list:
            string = string + e
        string = string + "Disjunctions:\n"
        for djn in self.disjunctions_list:
            string = string + "Disjunction: " + djn[0] + "\n"
            for disj in djn[1]:
                string = string + "  " + disj[0] + " : " + "\n"
                for c in disj[1]:
                    string = string + "    " + c + "\n"
        return string

    def __init__(self, model=None, logger=None):
        self.variable_label_map = SymbolMap(NumericLabeler('x'))
        self.prefix_expr_list = self._get_default_functions()
        self.variable_list = []
        self.bounds_list = []
        self.expression_list = []
        self.disjunctions_list = []
        self.walker = SMT_visitor(self.variable_label_map)
        self.solver = z3.Solver()
        self.logger = logger
        if model is not None:
            self._process_model(model)

    # Set up functions to be added to beginning of string
    def _get_default_functions(self):
        default = list()
        default.append("(define-fun exp ((x Real)) Real (^ %0.15f x))" %
                       (math.exp(1), ))
        return default

    # processes pyomo model into SMT model
    def _process_model(self, model):
        for v in model.component_data_objects(ctype=Var, descend_into=True):
            smtstring = self.add_var(v)
        for c in model.component_data_objects(ctype=Constraint, active=True):
            self.add_expr(c.expr)
        for djn in model.component_data_objects(ctype=Disjunction):
            if djn.active:
                self._process_active_disjunction(djn)
            else:
                self._process_inactive_disjunction(djn)

    # define bound constraints
    def _add_bound(self, var):
        nm = self.variable_label_map.getSymbol(var)
        lb = var.lb
        ub = var.ub
        if lb is not None:
            self.bounds_list.append("(assert (>= " + nm + " " + str(lb) +
                                    "))\n")
        if ub is not None:
            self.bounds_list.append("(assert (<= " + nm + " " + str(ub) +
                                    "))\n")

    # define variables
    def add_var(self, var):
        label = self.variable_label_map.getSymbol(var)
        domain = var.domain
        if var.is_continuous():
            self.variable_list.append("(declare-fun " + label + "() Real)\n")
            self._add_bound(var)
        elif var.is_binary():
            self.variable_list.append("(declare-fun " + label + "() Int)\n")
            self._add_bound(var)
        elif var.is_integer():
            self.variable_list.append("(declare-fun " + label + "() Int)\n")
            self._add_bound(var)
        else:
            raise NotImplementedError("SMT cannot handle " + str(domain) +
                                      " variables")
        return label

    # Defines SMT expression from pyomo expression
    def add_expr(self, expression):
        try:
            smtexpr = self.walker.walk_expression(expression)
            self.expression_list.append("(assert " + smtexpr + ")\n")
        except NotImplementedError as e:
            if self.logger is not None:
                self.logger.warning("Skipping Expression: " + str(e))

    # Computes the SMT Model for the disjunction from the internal class storage
    def _compute_disjunction_string(self, smt_djn):
        djn_string = smt_djn[0]
        for disj in smt_djn[1]:
            cons_string = "true"
            for c in disj[1]:
                cons_string = "(and " + cons_string + " " + c + ")"
            djn_string = djn_string + "(assert (=> ( = 1 " + disj[
                0] + ") " + cons_string + "))\n"
        return djn_string

    # converts disjunction to internal class storage
    def _process_active_disjunction(self, djn):
        or_expr = "0"
        disjuncts = []
        for disj in djn.disjuncts:
            constraints = []
            iv = disj.indicator_var
            label = self.add_var(iv)
            or_expr = "(+ " + or_expr + " " + label + ")"
            for c in disj.component_data_objects(ctype=Constraint,
                                                 active=True):
                try:
                    constraints.append(self.walker.walk_expression(c.expr))
                except NotImplementedError as e:
                    if self.logger is not None:
                        self.logger.warning("Skipping Disjunct Expression: " +
                                            str(e))
            disjuncts.append((label, constraints))
        if djn.xor:
            or_expr = "(assert (= 1 " + or_expr + "))\n"
        else:
            or_expr = "(assert (>= 1 " + or_expr + "))\n"
        self.disjunctions_list.append((or_expr, disjuncts))

    # processes inactive disjunction indicator vars without constraints
    def _process_inactive_disjunction(self, djn):
        or_expr = "0"
        for disj in djn.disjuncts:
            iv = disj.indicator_var
            label = self.add_var(iv)
            or_expr = "(+ " + or_expr + " " + label + ")"
        if djn.xor:
            or_expr = "(assert (= 1 " + or_expr + "))\n"
        else:
            or_expr = "(assert (>= 1 " + or_expr + "))\n"
        self.expression_list.append(or_expr)

    def get_SMT_string(self):
        prefix_string = ''.join(self.prefix_expr_list)
        variable_string = ''.join(self.variable_list)
        bounds_string = ''.join(self.bounds_list)
        expression_string = ''.join(self.expression_list)
        disjunctions_string = ''.join([
            self._compute_disjunction_string(d) for d in self.disjunctions_list
        ])
        smtstring = prefix_string + variable_string + bounds_string + expression_string + disjunctions_string
        return smtstring

    def get_var_dict(self):
        labels = [x for x in self.variable_label_map.bySymbol]
        labels.sort()
        vars = [self.variable_label_map.getObject(l) for l in labels]
        return zip(labels, vars)

    # Checks Satisfiability of model
    def check(self):
        self.solver.append(z3.parse_smt2_string(self.get_SMT_string()))
        return self.solver.check()