def toYicesTerms(): retval = [] for i in range(0, Configuration.bot_count): retval.append( Terms.eq( Terms.application(YicesSignature.b_op, [YicesSignature.integer(i)]), YicesSignature.thing_map[SymbolTable.bot_name(i)])) #sb.append(f'(assert (= (b {i}) b{i}))\n') for i in range(0, Configuration.pt2_count): x = i / Configuration.grid_dimension[1] y = i % Configuration.grid_dimension[1] retval.append( Terms.eq( Terms.application( YicesSignature.pt_op, [YicesSignature.integer(x), YicesSignature.integer(y)]), YicesSignature.pt2_map[SymbolTable.pt2_name(i)])) #sb.append(f'(assert (= (pt {x} {y}) pt_{x}_{y}))\n') return retval
def toConstraintTerm(self, maxTimeStamp=None): if self.name == SymbolTable.MAXTIME: assert maxTimeStamp is not None yterm = Terms.get_by_name(SymbolTable.MAXTIME) assert yterm is not None return Terms.eq(yterm, YicesSignature.integer(maxTimeStamp)) def constrainVariable(maxValue): if maxValue is not None: ymax = None if maxValue == SymbolTable.MAXTIME: ymax = Terms.get_by_name(SymbolTable.MAXTIME) else: ymax = YicesSignature.integer(maxValue) yterms = [ Terms.arith_leq_atom(YicesSignature.integer(0), self.yices_term), Terms.arith_leq_atom(self.yices_term, ymax) ] return Terms.yand(yterms) return Terms.arith_leq_atom(YicesSignature.integer(0), self.yices_term) if self.vartype.name == SymbolTable.TIME: return constrainVariable(SymbolTable.MAXTIME) if self.vartype.name == SymbolTable.STAGE: return constrainVariable(Configuration.stage_count - 1) if self.vartype.name == SymbolTable.NAT: if self.yices_type == SymbolTable.BINDEX: return constrainVariable(Configuration.bot_count - 1) if self.yices_type == SymbolTable.OBINDEX: return constrainVariable(Configuration.obs_count - 1) if self.yices_type == SymbolTable.XAXIS: return constrainVariable(Configuration.grid_dimension[0] - 1) if self.yices_type == SymbolTable.YAXIS: return constrainVariable(Configuration.grid_dimension[1] - 1) return None
def declare_functions(): assert None not in (YicesSignature.thing_type, YicesSignature.pt2_type, YicesSignature.stage_type, YicesSignature.time_type, YicesSignature.stage_type) YicesSignature.b_op = Terms.new_uninterpreted_term( YicesSignature.b_type, SymbolTable.B) if YicesSignature.b_op is None: sys.stderr.write( 'declare_functions: YicesSignature.b_op is none {0}\n', Yices.error_string()) YicesSignature.op_map[SymbolTable.B] = YicesSignature.b_op YicesSignature.ob_op = Terms.new_uninterpreted_term( YicesSignature.ob_type, SymbolTable.OB) if YicesSignature.ob_op is None: sys.stderr.write( 'declare_functions: YicesSignature.ob_op is none {0}\n', Yices.error_string()) YicesSignature.op_map[SymbolTable.OB] = YicesSignature.ob_op YicesSignature.pt_op = Terms.new_uninterpreted_term( YicesSignature.pt_type, SymbolTable.PT) if YicesSignature.pt_op is None: sys.stderr.write( 'declare_functions: YicesSignature.pt_op is none {0}\n', Yices.error_string()) YicesSignature.op_map[SymbolTable.PT] = YicesSignature.pt_op YicesSignature.atloc_op = Terms.new_uninterpreted_term( YicesSignature.atloc_type, SymbolTable.ATLOC) if YicesSignature.atloc_op is None: sys.stderr.write( 'declare_functions: YicesSignature.atloc_op is none {0}\n', Yices.error_string()) YicesSignature.op_map[SymbolTable.ATLOC] = YicesSignature.atloc_op YicesSignature.treatstage_op = Terms.new_uninterpreted_term( YicesSignature.treatstage_type, SymbolTable.TREATSTAGE) if YicesSignature.treatstage_op is None: sys.stderr.write( 'declare_functions: YicesSignature.treatstage_op is none {0}\n', Yices.error_string()) YicesSignature.op_map[ SymbolTable.TREATSTAGE] = YicesSignature.treatstage_op # DANGER: python2 crazyness! Enter at own risk!! YicesSignature.abs_op = Terms.abs YicesSignature.op_map[ SymbolTable. ABS] = Terms.abs # cannot use YicesSignature.abs_op because it has been mangled into an "unbound method"!!!! #print(f'YicesSignature.abs_op = {YicesSignature.abs_op}') #print(f'YicesSignature.op_map[SymbolTable.ABS] = {YicesSignature.op_map[SymbolTable.ABS]}') return True
def model2term(model): termlist = [] for i in range(9): for j in range(9): if self.game.puzzle.get_cell(i, j) is None: val = model.get_value(self.variables[i][j]) var = self.variables[i][j] value = self.numerals[val] termlist.append(Terms.arith_eq_atom(var, value)) return Terms.yand(termlist)
def constrainVariable(maxValue): if maxValue is not None: ymax = None if maxValue == SymbolTable.MAXTIME: ymax = Terms.get_by_name(SymbolTable.MAXTIME) else: ymax = YicesSignature.integer(maxValue) yterms = [ Terms.arith_leq_atom(YicesSignature.integer(0), self.yices_term), Terms.arith_leq_atom(self.yices_term, ymax) ] return Terms.yand(yterms) return Terms.arith_leq_atom(YicesSignature.integer(0), self.yices_term)
def declare_variable(var, bound_variables): """ constructs the yices term associated with the logical variable. In the case that bound_variables is not None, we are parsing an invariant, so that any NEW variables that we see are taken to be bound by the implicit universal quantifiers. """ varname = var.name vartype = var.vartype # check if it is bound and has already been seen if bound_variables is not None and varname in bound_variables: yvar = bound_variables[varname].yices_term var.bound = True return yvar # check if it has already been seen yvar = Terms.get_by_name(varname) if yvar is not None: #now we need to see if it is free or bound tag = Terms.constructor(yvar) if tag == Constructor.VARIABLE: var.bound = True bound_variables[varname] = var return yvar type_term = vartype.yices_term type_name = vartype.name var_term = None if bound_variables is not None: # we need to make a yices variable not an uninterpreted term var_term = Terms.new_variable(type_term, varname) if var_term is None: sys.stderr.write( f'declare_variable: Term.new_variable failed {Yices.error_string()}\n' ) return None bound_variables[varname] = var var.bound = True else: var_term = Terms.new_uninterpreted_term(type_term, varname) if var_term is None: sys.stderr.write( f'declare_variable: Term.new_uninterpreted_term failed {Yices.error_string()}\n' ) return None YicesSignature.types_to_variables[type_name].add(var) return var_term
def toYicesTermNondecreasing(self, height): retval = [] args = [] varlist = self.varlist[0:height] for v in varlist: yv = v.toYicesTerm() args.append(yv) for i, yarg in enumerate(args): if i > 0: yterm = Terms.arith_leq_atom(args[i - 1], yarg) assert yterm is not None retval.append(yterm) return Terms.yand(retval)
def integer(i): i = int(i) retval = YicesSignature.integer_map.get(i, None) if retval is None: retval = Terms.integer(i) YicesSignature.integer_map[i] = retval return retval
def count_models(self, debug): """count_model returns the number of distinct solutions/models to the current problem.""" def model2term(model): termlist = [] for i in range(9): for j in range(9): if self.game.puzzle.get_cell(i, j) is None: val = model.get_value(self.variables[i][j]) var = self.variables[i][j] value = self.numerals[val] termlist.append(Terms.arith_eq_atom(var, value)) return Terms.yand(termlist) result = 0 context = Context() self.assert_puzzle(context, self.game.puzzle) self.assert_rules(context) while context.check_context(None) == Status.SAT: model = Model.from_context(context, 1) diagram = model2term(model) if debug: print(f'\nModel #{result + 1}:') puzzle = self.puzzle_from_model(model, True) puzzle.pprint() context.assert_formula(Terms.ynot(diagram)) model.dispose() result += 1 if result >= self.game.options.aleph_nought: break context.dispose() return result
def _toYicesTermQF(self, maxTimeStamp): variables = [ v.yices_term for v in self.bv ] antecedent = self.event.yices_term consequent = self.constraint.yices_term conjuncts = [] body = Terms.ite(antecedent, consequent, Terms.TRUE) #Terms.print_to_fd(1, body, 120, 40, 0) self.init_space(maxTimeStamp) while not self.space.finished(): point = self.space.nextElement() values = [] for index, elem in enumerate(point): values.append(SymbolTable.get_type_element_as_yices_term(elem, self.var_types[index])) conjunct = Terms.subst(variables, values, body) #Terms.print_to_fd(1, conjunct, 120, 40, 0) conjuncts.append(conjunct) return Terms.yand(conjuncts)
def toYicesTermDistinct(self, height): args = [] varlist = self.varlist[0:height] for v in varlist: yv = v.toYicesTerm() args.append(yv) yterm = Terms.distinct(args) assert yterm is not None return yterm
def model2term(model): termlist = [] #do the times for tvar in YicesSignature.get_vars(SymbolTable.TIME): ytvar = tvar.yices_term ytval = model.get_value_as_term(ytvar) termlist.append(Terms.arith_eq_atom(ytvar, ytval)) #do the points for ptvar in YicesSignature.get_vars(SymbolTable.PT2): ytvar = ptvar.yices_term ytval = model.get_value(ytvar) termlist.append(Terms.eq(ytvar, ytval)) #do the stages # FIXME: more stuff needed here return Terms.yand(termlist)
def toYicesTermIncrementally(self, level): assert level in range(1, 4) retval = [] if level >= 1: yterm = self.toYicesTermDistinct(height=None) retval.append(yterm) if level >= 2: yterm = self.toYicesTermAscending(height=None) retval.append(yterm) return Terms.yand(retval)
def get_yices_op(name): yices_term = None # treat abs a bit differently because it maps directly to a yices op, just like the infix ops. if name == SymbolTable.ABS: op_term = YicesSignature.op_map[name] yices_term = lambda args: op_term(args[0]) elif name in YicesSignature.op_map: op_term = YicesSignature.op_map[name] yices_term = lambda args: Terms.application(op_term, args) elif name in SymbolTable.binop_map: yices_term = lambda args: SymbolTable.binop_map[name](args[0], args[1]) elif name in SymbolTable.infix_map: yices_term = lambda args: SymbolTable.infix_map[name](args[0], args[1]) assert yices_term is not None return yices_term
def mktreatstage(pt, stage, timestamp): pt_term = YicesSignature.pt2_map.get(pt, None) if pt_term is None: sys.stderr.write('assert_atloc: no pt called {0}\n'.format(pt)) return None stage_term = YicesSignature.integer(stage) time_term = YicesSignature.integer(timestamp) application = Terms.application(YicesSignature.treatstage_op, [pt_term, stage_term, time_term]) if application is None: sys.stderr.write('assert_atloc: Terms.application failed {0}\n'.format(Yices.error_string())) return None return application
def mkatloc(bot, pt, timestamp): bot_term = YicesSignature.thing_map.get(bot, None) if bot_term is None: sys.stderr.write('mkatloc: no bot called {0}\n'.format(bot)) return None pt_term = YicesSignature.pt2_map.get(pt, None) if pt_term is None: sys.stderr.write('mkatloc: no pt called {0}\n'.format(pt)) return None time_term = YicesSignature.integer(timestamp) application = Terms.application(YicesSignature.atloc_op, [bot_term, pt_term, time_term]) if application is None: sys.stderr.write('mkatloc: Terms.application failed {0}\n'.format(Yices.error_string())) return None return application
def _toYicesTermQ(self): variables = [v.yices_term for v in self.bv] antecedent = self.event.yices_term consequent = self.constraint.yices_term body = Terms.ite(antecedent, consequent, Terms.TRUE) return Terms.forall(variables, body)