Exemple #1
0
 def _compute_WMI_PA_no_boolean(self, lab_formula, pa_vars, labels, other_assignments={}):
     """Finds all the assignments that satisfy the given formula using AllSAT.
         
     Args:
         lab_formula (FNode): The labelled pysmt formula to examine.
         pa_vars (): 
         labels (dict): The dictionary containing the correlation between each label and their
             true value.
         
     Yields:
         dict: One of the assignments that satisfies the formula.
     
     """
     solver = Solver(name="msat",
                 solver_options={"dpll.allsat_minimize_model" : "true"})
     converter = solver.converter
     solver.add_assertion(lab_formula)
     lra_assignments = []
     mathsat.msat_all_sat(
         solver.msat_env(),
         [converter.convert(v) for v in pa_vars],
         lambda model : WMI._callback(model, converter, lra_assignments))
     for mu_lra in lra_assignments:                    
         assignments = {}
         for atom, value in WMI._get_assignments(mu_lra).items():
             if atom in labels:
                 atom = labels[atom]
             assignments[atom] = value
         assignments.update(other_assignments)
         yield assignments
Exemple #2
0
 def _compute_TTAs(self, formula):
     """Computes the total truth assignments of the given formula.
     
     This method first labels the formula and then uses the funtionality of mathsat called AllSAT to
         retrieve all the total truth assignments.
     
     Args:
         formula (FNode): The pysmt formula to examine.
     
     Returns:
         list: The list of all the total truth assignments.
         dict: The dictionary containing all the correspondence between the labels and their true value.
         
     """
     labels = {}
     expressions = []
     allsat_variables = set()
     
     # Label LRA atoms with fresh boolean variables
     labelled_formula, pa_vars, labels = self.label_formula(formula, formula.get_atoms())
     
     # Perform AllSMT on the labelled formula
     solver = Solver(name="msat")
     converter = solver.converter
     solver.add_assertion(labelled_formula)
     models = []
     mathsat.msat_all_sat(solver.msat_env(),
                     [converter.convert(v) for v in pa_vars],
                     lambda model : WMI._callback(model, converter, models))
     return models, labels
Exemple #3
0
def callback(model, converter, result):
    """Callback for msat_all_sat.

    This function is called by the MathSAT API everytime a new model
    is found. If the function returns 1, the search continues,
    otherwise it stops.
    """
    # Elements in model are msat_term .
    # Converter.back() provides the pySMT representation of a solver term.
    py_model = [converter.back(v) for v in model]
    result.append(And(py_model))
    return 1 # go on

x, y = Symbol("x"), Symbol("y")
f = Or(x, y)

msat = Solver(name="msat")
converter = msat.converter # .converter is a property implemented by all solvers
msat.add_assertion(f) # This is still at pySMT level

result = []
# Directly invoke the mathsat API !!!
# The second term is a list of "important variables"
mathsat.msat_all_sat(msat.msat_env(),
      [converter.convert(x)],      # Convert the pySMT term into a MathSAT term
      lambda model : callback(model, converter, result))

print("'exists y . %s' is equivalent to '%s'" %(f, Or(result)))
#exists y . (x | y) is equivalent to ((! x) | x)
Exemple #4
0
    """Callback for msat_all_sat.

    This function is called by the MathSAT API everytime a new model
    is found. If the function returns 1, the search continues,
    otherwise it stops.
    """
    # Elements in model are msat_term .
    # Converter.back() provides the pySMT representation of a solver term.
    py_model = [converter.back(v) for v in model]
    result.append(And(py_model))
    return 1  # go on


x, y = Symbol("x"), Symbol("y")
f = Or(x, y)

msat = Solver(name="msat")
converter = msat.converter  # .converter is a property implemented by all solvers
msat.add_assertion(f)  # This is still at pySMT level

result = []
# Directly invoke the mathsat API !!!
# The second term is a list of "important variables"
mathsat.msat_all_sat(
    msat.msat_env(),
    [converter.convert(x)],  # Convert the pySMT term into a MathSAT term
    lambda model: callback(model, converter, result))

print("'exists y . %s' is equivalent to '%s'" % (f, Or(result)))
#exists y . (x | y) is equivalent to ((! x) | x)
Exemple #5
0
    def _compute_WMI_PA(self, formula, weights):
        """Computes WMI using the Predicate Abstraction (PA) algorithm.
        
        Args:
            formula (FNode): The formula on whick to compute WMI.
            weights (Weight): The corresponding weight.
            
        Returns:
            real: The final volume of the integral computed by summing up all the integrals' results.
            int: The number of problems that have been computed.
        
        """
        problems = []
        boolean_variables = get_boolean_variables(formula)
        if len(boolean_variables) == 0:
            # Enumerate partial TA over theory atoms
            lab_formula, pa_vars, labels = self.label_formula(formula, formula.get_atoms())
            # Predicate abstraction on LRA atoms with minimal models
            for assignments in self._compute_WMI_PA_no_boolean(lab_formula, pa_vars, labels):
                problem = self._create_problem(assignments, weights)
                problems.append(problem)
        else:
            solver = Solver(name="msat")
            converter = solver.converter
            solver.add_assertion(formula)
            boolean_models = []
            # perform AllSAT on the Boolean variables
            mathsat.msat_all_sat(
                solver.msat_env(),
                [converter.convert(v) for v in boolean_variables],
                lambda model : WMI._callback(model, converter, boolean_models))

            logger.debug("n_boolean_models: {}".format(len(boolean_models)))
            # for each boolean assignment mu^A of F        
            for model in boolean_models:
                atom_assignments = {}
                boolean_assignments = WMI._get_assignments(model)
                atom_assignments.update(boolean_assignments)
                subs = {k : Bool(v) for k, v in boolean_assignments.items()}
                f_next = formula
                # iteratively simplify F[A<-mu^A], getting (possibily part.) mu^LRA
                while True:            
                    f_before = f_next
                    f_next = simplify(substitute(f_before, subs))
                    lra_assignments, over = WMI._parse_lra_formula(f_next)
                    subs = {k : Bool(v) for k, v in lra_assignments.items()}
                    atom_assignments.update(lra_assignments)
                    if over or lra_assignments == {}:
                        break
                if not over:
                    # predicate abstraction on LRA atoms with minimal models
                    lab_formula, pa_vars, labels = self.label_formula(f_next, f_next.get_atoms())
                    expressions = []
                    for k, v in atom_assignments.items():
                        if k.is_theory_relation():
                            if v:
                                expressions.append(k)
                            else:
                                expressions.append(Not(k))
                                                
                    lab_formula = And([lab_formula] + expressions)
                    for assignments in self._compute_WMI_PA_no_boolean(lab_formula, pa_vars, labels, atom_assignments):
                        problem = self._create_problem(assignments, weights)
                        problems.append(problem)
                else:
                    # integrate over mu^A & mu^LRA
                    problem = self._create_problem(atom_assignments, weights)
                    problems.append(problem)

        results, cached = self.integrator.integrate_batch(problems, self.cache)
        volume = fsum(results)
        return volume, len(problems)-cached, cached