def test_ackermannization_explicit(self): self.env.enable_infix_notation = True a, b = (Symbol(x, INT) for x in "ab") f, g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) # Explicit the Ackermanization of this expression We end up # with a conjunction of implications that is then conjoined # with the original formula. ackermannization = Ackermannizer() actual_ack = ackermannization.do_ackermannization(formula1) terms_to_consts = ackermannization.get_term_to_const_dict() ack_h_a = terms_to_consts[h(a)] ack_h_b = terms_to_consts[h(b)] ack_g_a_h_a = terms_to_consts[g(a, h(a))] ack_g_b_h_b = terms_to_consts[g(b, h(b))] ack_f_a_g_a_h_a = terms_to_consts[f(a, g(a, h(a)))] ack_f_b_g_b_h_b = terms_to_consts[f(b, g(b, h(b)))] target_ack = And( Equals(a, b).Implies(Equals(ack_h_a, ack_h_b)), And(Equals(a, b), Equals(ack_h_a, ack_h_b)).Implies(Equals(ack_g_a_h_a, ack_g_b_h_b)), And(Equals(a, b), Equals(ack_h_a, ack_h_b), Equals(ack_g_a_h_a, ack_g_b_h_b)).Implies( Equals(ack_f_a_g_a_h_a, ack_f_b_g_b_h_b))) target_ack = And(target_ack, Not(Equals(ack_f_a_g_a_h_a, ack_f_b_g_b_h_b))) self.assertValid(target_ack.Iff(actual_ack))
def test_ackermannization_explicit(self): self.env.enable_infix_notation = True a,b = (Symbol(x, INT) for x in "ab") f,g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) # Explicit the Ackermanization of this expression We end up # with a conjunction of implications that is then conjoined # with the original formula. ackermannization = Ackermannizer() actual_ack = ackermannization.do_ackermannization(formula1) terms_to_consts = ackermannization.get_term_to_const_dict() ack_h_a = terms_to_consts[h(a)] ack_h_b = terms_to_consts[h(b)] ack_g_a_h_a = terms_to_consts[g(a, h(a))] ack_g_b_h_b = terms_to_consts[g(b, h(b))] ack_f_a_g_a_h_a = terms_to_consts[f(a, g(a, h(a)))] ack_f_b_g_b_h_b = terms_to_consts[f(b, g(b, h(b)))] target_ack = And( Equals(a, b).Implies(Equals(ack_h_a, ack_h_b)), And(Equals(a, b), Equals(ack_h_a, ack_h_b)).Implies( Equals(ack_g_a_h_a, ack_g_b_h_b)), And(Equals(a, b), Equals(ack_h_a, ack_h_b), Equals(ack_g_a_h_a, ack_g_b_h_b)).Implies( Equals(ack_f_a_g_a_h_a, ack_f_b_g_b_h_b))) target_ack = And(target_ack, Not(Equals(ack_f_a_g_a_h_a, ack_f_b_g_b_h_b))) self.assertValid(target_ack.Iff(actual_ack))
def test_ackermannization_dictionaries(self): self.env.enable_infix_notation = True a, b = (Symbol(x, INT) for x in "ab") f, g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) ackermannization = Ackermannizer() _ = ackermannization.do_ackermannization(formula) terms_to_consts = ackermannization.get_term_to_const_dict() consts_to_terms = ackermannization.get_const_to_term_dict() # The maps have the same length self.assertEqual(len(terms_to_consts), len(consts_to_terms)) # The maps are the inverse of each other for t in terms_to_consts: self.assertEqual(t, consts_to_terms[terms_to_consts[t]]) # Check that the the functions are there for atom in formula.get_atoms(): if atom.is_function_application(): self.assertIsNotNone(terms_to_consts[atom])
def test_ackermannization_dictionaries(self): self.env.enable_infix_notation = True a,b = (Symbol(x, INT) for x in "ab") f,g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) ackermannization = Ackermannizer() _ = ackermannization.do_ackermannization(formula) terms_to_consts = ackermannization.get_term_to_const_dict() consts_to_terms = ackermannization.get_const_to_term_dict() # The maps have the same length self.assertEqual(len(terms_to_consts), len(consts_to_terms)) # The maps are the inverse of each other for t in terms_to_consts: self.assertEqual(t, consts_to_terms[terms_to_consts[t]]) # Check that the the functions are there for atom in formula.get_atoms(): if atom.is_function_application(): self.assertIsNotNone(terms_to_consts[atom])
def _solve_with_dreal(self, formula): #ackermanization ackermanization = Ackermannizer() h = Skolemization(self._env) skolemized_formula = h.simple_skolemization(formula) ackermized_formula = ackermanization.do_ackermannization( skolemized_formula) pure_formula = Purifications.real_int_purify(ackermized_formula) #filtered_formulas = self._filter_formulas(formulas) #formula = And(filtered_formulas) limited_smt_printer = LimitedSmtPrinter() smtlib_data = "(set-logic QF_NRA)\n" + limited_smt_printer.printer( pure_formula) #dreal doesn't like to_real smtlib_data = smtlib_data.replace('to_real', '* 1 ') try: os.remove(DREAL_TMP_SMT_PATH) except OSError: pass try: os.remove(DREAL_MODEL_PATH) except OSError: pass open(DREAL_TMP_SMT_PATH, 'w').write(smtlib_data) dreal_command = [DREAL_BINARY] dreal_command.append("--model") if self._config.dreal_precision: dreal_command.extend(["--precision", self._config.dreal_precision]) dreal_command.append(DREAL_TMP_SMT_PATH) result_object = subprocess.run(dreal_command, stdout=subprocess.PIPE) result_string = result_object.stdout.decode('utf-8') result = self._parse_result_from_dreal(result_string) #take care of (get-value)s values = [] if result == SolverResult.SAT: #get dreal solution raw_values = self._parse_values_from_dreal(result_string) #get list of wanted values stream = cStringIO(self._smtlib) parser = ExtendedSmtLibParser(environment=self._env) script = parser.get_script(stream) exprs = [] #dreal_exprs = set([]) for get_val_cmd in script.filter_by_command_name("get-value"): exprs.extend(get_val_cmd.args) for expr in exprs: if expr in ackermanization.get_term_to_const_dict(): dreal_expr = ackermanization.get_term_to_const_dict()[expr] #dreal_exprs.add(dreal_expr) if dreal_expr in raw_values: value = raw_values[dreal_expr] else: value = '__' else: value = '__' values.append(value) values_no_spaces = [str(x).replace(' ', '') for x in values] return result, values_no_spaces