def addHistory(self): for clock in self.newClocks: history = None tick = self.tickDict["t_%s" % (clock)] if ("h_%s" % (clock)) not in self.historyDict.keys(): history = z3.Function("h_%s" % (clock), z3.IntSort(), z3.IntSort()) self.historyDict["h_%s" % (clock)] = history else: history = self.historyDict["h_%s" % (clock)] # self.solver.add(history(0) == z3.IntVal(0)) self.solver.add(history(1) == z3.IntVal(0)) if self.bound > 0: # If the bound is finite, we define the history of the clock with a fixed bound. for i in range(1, self.bound + 1): self.solver.add( z3.If(tick(i), history(i + 1) == history(i) + 1, history(i + 1) == history(i))) # self.solver.add(z3.If(tick(i), # history(i + 1) == history(i) + 1, # history(i + 1) == history(i))) elif self.bound == 0: x = z3.Int("x") # If the bound is infinite, we define the history of the clock infinitely. self.solver.add( z3.ForAll( x, z3.Implies( x >= 1, z3.If(tick(x), history(x + 1) == history(x) + 1, history(x + 1) == history(x)))))
def addTickSMT(self): for each in self.newClocks: self.tickDict["t_%s" % (each)] = z3.Function( "t_%s" % (each), z3.IntSort(), z3.BoolSort()) tick = self.tickDict["t_%s" % (each)] if self.bound > 0: y = z3.Int("y") if self.period > 0: for y in range(1, self.bound + 1): self.solver.add( z3.Implies( y >= self.k, tick((y - self.l) % self.p + self.l) == tick(y))) # self.solver.add( # z3.ForAll(y,z3.Implies( # z3.And(y >= self.k,y <= self.bound), # tick((y - self.l) % self.p + self.l) == tick(y)))) elif self.bound == 0: x = z3.Int("x") if self.period > 0: y = z3.Int("y") self.solver.add( z3.ForAll( y, z3.Implies( y >= self.k, tick((y - self.l) % self.p + self.l) == tick(y)))) clockListTmp = [] x = z3.Int("x") for each in self.tickDict.keys(): tick = self.tickDict[each] clockListTmp.append(tick(x)) if self.bound == 0: self.solver.add( z3.ForAll(x, z3.Implies(x >= 1, z3.Or(clockListTmp)))) else: for i in range(1, self.bound + 1): tmp = [] for tick in self.tickDict.values(): tmp.append(tick(i)) self.solver.add(z3.Or(tmp))
def addTickStep(self, clock): tick = self.tickDict["t_%s" % (clock)] history = self.historyDict["h_%s" % (clock)] if "s_%s" % (clock) not in self.tickStep.keys(): tickStep = z3.Function("s_%s" % (clock), z3.IntSort(), z3.IntSort()) self.tickStep["s_%s" % (clock)] = tickStep if self.bound > 0: x = z3.Int("x") # If the bound is infinite, we define the history of the clock infinitely. for i in range(1, self.bound + 1): self.solver.add( z3.Implies(tick(i), tickStep(history(i) + 1) == i)) elif self.bound == 0: x = z3.Int("x") # If the bound is infinite, we define the history of the clock infinitely. self.solver.add( z3.ForAll( x, z3.Implies(z3.And(x >= 1, tick(x)), tickStep(history(x) + 1) == x)))
def addTickForever(self): """ Adding a clock msec, which ticks every step, represents the real-time. :return: """ if "msec" in self.oldClocks: tick = self.tickDict["t_%s" % ("msec")] if self.bound > 0: for i in range(1, self.bound + 1): self.solver.add(tick(i) == True) else: x = z3.Int("x") self.solver.add( z3.ForAll(x, z3.Implies(x >= 1, tick(x) == True)))
def generate_assignments(thresh=2): solver = z3.Solver() # Block 1 block_1 = {'b1_1': 'move'} block_1_obj = SMT_Block(block_1, thresh) values = block_1_obj.block_values block_1_vars = [ele.var for ele in block_1_obj.block_z3_vars ] # for the conditional constraints c1 = z3.Int('c1') # bool_path_left (if_only) values.append(z3.Or(c1 == 8, c1 == 9)) block_2 = {'b2_1': 'turn_left'} block_2_obj = SMT_Block(block_2, thresh) values.extend(block_2_obj.block_values) block_2_vars = [ele.var for ele in block_2_obj.block_z3_vars ] # for the conditional constraints block_3 = {'b3_1': 'phi'} block_3_obj = SMT_Block(block_3, thresh) values.extend(block_3_obj.block_values) block_3_vars = [ele.var for ele in block_3_obj.block_z3_vars ] # for the conditional constraints # all block objects block_objs = [block_1_obj, block_2_obj, block_3_obj] X = [ele.var for ele in block_1_obj.block_z3_vars ] # added the variables for block 1 X.append(c1) # added the conditional variable X.extend([ele.var for ele in block_2_obj.block_z3_vars ]) # added the variables for block 2 X.extend([ele.var for ele in block_3_obj.block_z3_vars ]) # added the variables for block 3 constraints = block_1_obj.block_append_constraints + block_1_obj.flip_turns_constraints + block_1_obj.block_elimination_constraints + \ block_2_obj.block_append_constraints + block_2_obj.flip_turns_constraints + block_2_obj.block_elimination_constraints + \ block_3_obj.block_append_constraints + block_3_obj.flip_turns_constraints + block_3_obj.block_elimination_constraints single_block_change_cons = single_block_change(block_objs) constraints.extend(single_block_change_cons) constraints.extend([ # conditional constraints: if(path_left) z3.Implies(c1 == 8, z3.Or(block_2_vars[0] == 2, block_2_vars[1] == 2, block_2_vars[2] == 2, block_2_vars[3] == 2, block_2_vars[4] == 2, )), z3.Implies(z3.And(c1 == 8, block_2_vars[1] == 2, block_2_vars[0] != 2), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 3 )), z3.Implies(z3.And(c1 == 8, block_2_vars[2] == 2, block_2_vars[0] != 2, block_2_vars[1] != 2), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 3, block_2_vars[1] != 1, block_2_vars[1] != 3)), z3.Implies(z3.And(c1 == 8, block_2_vars[3] == 2, block_2_vars[0] != 2, block_2_vars[1] != 2, block_2_vars[2] != 2), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 3, block_2_vars[1] != 1, \ block_2_vars[1] != 3, block_2_vars[2] != 1, block_2_vars[2] != 3)), z3.Implies(z3.And(c1 == 8, block_2_vars[4] == 2, block_2_vars[0] != 2, block_2_vars[1] != 2, block_2_vars[2] != 2, block_2_vars[3] != 2), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 3, block_2_vars[1] != 1, block_2_vars[1] != 3, block_2_vars[2] != 1, block_2_vars[2] != 3, block_2_vars[3] != 1, block_2_vars[3] != 3)), # conditional constraints: if(path_right) z3.Implies(c1 == 9, z3.Or(block_2_vars[0] == 3, block_2_vars[1] == 3, block_2_vars[2] == 3, block_2_vars[3] == 3, block_2_vars[4] == 3, )), z3.Implies(z3.And(c1 == 9, block_2_vars[1] == 3, block_2_vars[0] != 3, ), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 2)), z3.Implies(z3.And(c1 == 9, block_2_vars[2] == 3, block_2_vars[0] != 3, block_2_vars[1] != 3), z3.And(block_2_vars[0]!= 1, block_2_vars[0] != 2, block_2_vars[1] != 1, block_2_vars[1] != 2)), z3.Implies(z3.And(c1 == 9, block_2_vars[3] == 3, block_2_vars[0] != 3, block_2_vars[1] != 3, block_2_vars[2] != 3), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 2, block_2_vars[1] != 1, block_2_vars[1] != 2, block_2_vars[2] != 1, block_2_vars[2] != 2)), z3.Implies(z3.And(c1 == 9, block_2_vars[4] == 3, block_2_vars[0] != 3, block_2_vars[1] != 3, block_2_vars[2] != 3, block_2_vars[3] != 3 ), z3.And(block_2_vars[0] != 1, block_2_vars[0] != 2, block_2_vars[1] != 1, block_2_vars[1] != 2, block_2_vars[2] != 1, block_2_vars[2] != 2, block_2_vars[3] != 1, block_2_vars[3] != 2)), ]) # add the values and the constraints solver.add(values + constraints) # generate all the assignments models = gen_all(solver, X) assignments = [] for model in models: a = ['repeat_until_goal(bool_goal)'] a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in X[:block_1_obj.size] ]) a.append(type_to_str[ConditionalType(model[c1].as_long())]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in X[block_1_obj.size + 1:] ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_3_vars ]) assignments.append(a) #print(a) #print('Found #{} SAT values'.format(len(models))) return assignments
def generate_assignments(thresh=2, id='karel'): solver = z3.Solver() # declare the SMT variables for the specific code # Block 1 block_1 = {'b1_1': 'put_marker'} block_1_obj = SMT_Block(block_1, thresh, id=id) values = block_1_obj.block_values block_1_vars = [ele.var for ele in block_1_obj.block_z3_vars ] # for the conditional constraints c1 = z3.Int('c1') # bool_path_ahead (while) values.append(z3.Or(c1 == 7, c1 == 12)) # bool_path_ahead, bool_no_path_ahead block_2 = { 'b2_1': 'move', 'b2_2': 'turn_left', 'b2_3': 'move', 'b2_4': 'turn_right', 'b2_5': 'put_marker' } block_2_obj = SMT_Block(block_2, thresh, id=id) values.extend(block_2_obj.block_values) block_2_vars = [ele.var for ele in block_2_obj.block_z3_vars ] # for the conditional constraints block_3 = {'b3_1': 'phi'} block_3_obj = SMT_Block(block_3, thresh, id=id) values.extend(block_3_obj.block_values) block_3_vars = [ele.var for ele in block_3_obj.block_z3_vars ] # for the conditional constraints # all block objects block_objs = [block_1_obj, block_2_obj, block_3_obj] X = [c1] X.extend([ele.var for ele in block_1_obj.block_z3_vars ]) # added the variables for block 1 X.extend([ele.var for ele in block_2_obj.block_z3_vars ]) # added the variables for block 2 X.extend([ele.var for ele in block_3_obj.block_z3_vars ]) # added the variables for block 3 constraints = block_1_obj.block_append_constraints + block_1_obj.flip_turns_constraints + block_1_obj.flip_marker_constraints+ \ block_1_obj.block_elimination_constraints + \ block_2_obj.block_append_constraints + block_2_obj.flip_turns_constraints + \ block_2_obj.flip_marker_constraints + block_2_obj.block_elimination_constraints +\ block_3_obj.block_append_constraints + block_3_obj.flip_turns_constraints + \ block_3_obj.flip_marker_constraints + block_3_obj.block_elimination_constraints single_block_change_cons = single_block_change(block_objs) constraints.extend(single_block_change_cons) constraints.extend([ # conditional constraints: while(bool_path_ahead)---while block constraints z3.Implies( c1 == 7, z3.Or( block_2_vars[0] == 1, block_2_vars[1] == 1, block_2_vars[2] == 1, block_2_vars[3] == 1, block_2_vars[4] == 1, block_2_vars[5] == 1, block_2_vars[6] == 1, block_2_vars[7] == 1, block_2_vars[8] == 1, block_2_vars[9] == 1, block_2_vars[10] == 1, block_2_vars[11] == 1, block_2_vars[12] == 1, )), z3.Implies(z3.And(c1 == 7, block_2_vars[1] == 1, block_2_vars[0] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[2] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[3] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[4] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[5] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[6] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[7] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[8] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3, block_2_vars[7] != 2, block_2_vars[7] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[9] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3, block_2_vars[7] != 2, block_2_vars[7] != 3, block_2_vars[8] != 2, block_2_vars[8] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[10] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3, block_2_vars[7] != 2, block_2_vars[7] != 3, block_2_vars[8] != 2, block_2_vars[8] != 3, block_2_vars[9] != 2, block_2_vars[9] != 3)), # # ################################################ THRESH = 2 z3.Implies( z3.And(c1 == 7, block_2_vars[11] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1, block_2_vars[10] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3, block_2_vars[7] != 2, block_2_vars[7] != 3, block_2_vars[8] != 2, block_2_vars[8] != 3, block_2_vars[9] != 2, block_2_vars[9] != 3, block_2_vars[10] != 2, block_2_vars[10] != 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[12] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1, block_2_vars[10] != 1, block_2_vars[11] != 1), z3.And(block_2_vars[0] != 2, block_2_vars[0] != 3, block_2_vars[1] != 2, block_2_vars[1] != 3, block_2_vars[2] != 2, block_2_vars[2] != 3, block_2_vars[3] != 2, block_2_vars[3] != 3, block_2_vars[4] != 2, block_2_vars[4] != 3, block_2_vars[5] != 2, block_2_vars[5] != 3, block_2_vars[6] != 2, block_2_vars[6] != 3, block_2_vars[7] != 2, block_2_vars[7] != 3, block_2_vars[8] != 2, block_2_vars[8] != 3, block_2_vars[9] != 2, block_2_vars[9] != 3, block_2_vars[10] != 2, block_2_vars[10] != 3, block_2_vars[11] != 2, block_2_vars[11] != 3)), # # conditional constraints: while(bool_no_path_ahead)---while block constraints z3.Implies(c1 == 12, block_2_vars[0] != 1), z3.Implies( z3.And(c1 == 12, block_2_vars[1] == 1, block_2_vars[0] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[2] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[3] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[4] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[5] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[6] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[7] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[8] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3, block_2_vars[7] == 2, block_2_vars[7] == 3)), z3.Implies( z3.And(c1 == 12, block_2_vars[9] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3, block_2_vars[7] == 2, block_2_vars[7] == 3, block_2_vars[8] == 2, block_2_vars[8] == 3)), z3.Implies( z3.And( c1 == 12, block_2_vars[10] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1, ), z3.Or( block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3, block_2_vars[7] == 2, block_2_vars[7] == 3, block_2_vars[8] == 2, block_2_vars[8] == 3, block_2_vars[9] == 2, block_2_vars[9] == 3, )), z3.Implies( z3.And(c1 == 12, block_2_vars[11] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1, block_2_vars[10] != 1), z3.Or( block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3, block_2_vars[7] == 2, block_2_vars[7] == 3, block_2_vars[8] == 2, block_2_vars[8] == 3, block_2_vars[9] == 2, block_2_vars[9] == 3, block_2_vars[10] == 2, block_2_vars[10] == 3, )), z3.Implies( z3.And(c1 == 12, block_2_vars[12] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1, block_2_vars[4] != 1, block_2_vars[5] != 1, block_2_vars[6] != 1, block_2_vars[7] != 1, block_2_vars[8] != 1, block_2_vars[9] != 1, block_2_vars[10] != 1, block_2_vars[11] != 1), z3.Or( block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3, block_2_vars[4] == 2, block_2_vars[4] == 3, block_2_vars[5] == 2, block_2_vars[5] == 3, block_2_vars[6] == 2, block_2_vars[6] == 3, block_2_vars[7] == 2, block_2_vars[7] == 3, block_2_vars[8] == 2, block_2_vars[8] == 3, block_2_vars[9] == 2, block_2_vars[9] == 3, block_2_vars[10] == 2, block_2_vars[10] == 3, block_2_vars[11] == 2, block_2_vars[11] == 3, )), ]) # add the values and the constraints solver.add(values + constraints) # generate all the assignments models = gen_all(solver, X) assignments = [] for model in models: a = [ type_to_str[VariableType(model[ele].as_long())] for ele in block_1_vars ] a.append(type_to_str[ConditionalType(model[c1].as_long())]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_2_vars ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_3_vars ]) assignments.append(a) #print(a) #print('Found #{} SAT values'.format(len(models))) return assignments
def addOriginSMTConstraints(self): """ Realize to transfer the CCSL constraints into SMT formula. :return: """ cnt = 0 for each in self.newCCSLConstraintList: if each[0] == "<" and len(each) == 3: tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add( z3.Implies( history1(i) == history2(i), z3.Not(tick2(i)))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n, history1(x) == history2(x)), # z3.Not(tick2(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies( z3.And(x >= 1, history1(x) == history2(x)), z3.Not(tick2(x))))) elif each[0] == "<" and len(each) == 4: tick1 = self.tickDict["t_%s" % (each[1])] delay = each[2] tick2 = self.tickDict["t_%s" % (each[3])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add( z3.Implies( history2(i) - history1(i) == delay, z3.Not(tick2(i)))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n, history2(x) - history1(x) == delay), # z3.Not(tick2(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies( z3.And(x >= 1, history2(x) - history1(x) == delay), z3.Not(tick2(x))))) elif each[0] == "≤": history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add(history1(i) >= history2(i)) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n + 1), # history1(x) >= history2(x)))) else: self.solver.add( z3.ForAll( x, z3.Implies(x >= 1, history1(x) >= history2(x)))) elif each[0] == "⊆": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 1): self.solver.add(z3.Implies(tick1(i), tick2(i))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n, tick1(x)), # tick2(x)))) else: self.solver.add( z3.ForAll( x, z3.Implies(z3.And(x >= 1, tick1(x)), tick2(x)))) elif each[0] == "#": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 1): self.solver.add( z3.Or(z3.Not(tick1(i)), z3.Not(tick2(i)))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n), # z3.Or(z3.Not(tick1(x)), z3.Not(tick2(x)))))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 1, z3.Or(z3.Not(tick1(x)), z3.Not(tick2(x)))))) elif each[0] == "+": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] tick3 = self.tickDict["t_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 1): self.solver.add(tick1(i) == z3.Or(tick2(i), tick3(i))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n), # tick1(x) == z3.Or(tick2(x), tick3(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies(x >= 1, tick1(x) == z3.Or(tick2(x), tick3(x))))) elif each[0] == "*": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] tick3 = self.tickDict["t_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 1): self.solver.add( z3.Implies(tick1(i), z3.And(tick2(i), tick3(i)))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n), # tick1(x) == z3.And(tick2(x), tick3(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies(x >= 1, tick1(x) == z3.And(tick2(x), tick3(x))))) elif each[0] == "∧": history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] history3 = self.historyDict["h_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add( history1(i) == z3.If( history2(i) >= history3(i), history2(i), history3(i))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n + 1), # history1(x) == z3.If(history2(x) >= history3(x),history2(x),history3(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 1, history1(x) == z3.If( history2(x) >= history3(x), history2(x), history3(x))))) elif each[0] == "∨": history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] history3 = self.historyDict["h_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add( history1(i) == z3.If( history2(i) <= history3(i), history2(i), history3(i))) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n + 1), # history1(x) == z3.If(history2(x) <= history3(x), history2(x), history3(x))))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 1, history1(x) == z3.If( history2(x) <= history3(x), history2(x), history3(x))))) elif each[0] == "$": history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] delay = z3.IntVal(int(each[3])) x = z3.Int("x") if self.bound > 0: for i in range(1, self.bound + 2): self.solver.add( history1(i) == z3.If( history2(i) >= delay, history2(i) - delay, 0)) # self.solver.add(z3.ForAll(x, z3.Implies( # z3.And(x >= 1, x <= self.n + 1), # history1(x) == z3.If(history2(x) >= delay,history2(x) - delay,0)))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 1, history1(x) == z3.If( history2(x) >= delay, history2(x) - delay, 0)))) elif each[0] == "on": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] tick3 = self.tickDict["t_%s" % (each[4])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] history3 = self.historyDict["h_%s" % (each[4])] self.addTickStep(each[1]) self.addTickStep(each[2]) self.addTickStep(each[4]) tickStep1 = self.tickStep["s_%s" % (each[1])] tickStep2 = self.tickStep["s_%s" % (each[2])] tickStep3 = self.tickStep["s_%s" % (each[4])] x = z3.Int("x") if self.bound > 0: for i in range(1, int(each[3]) + 1): self.solver.add(z3.Not(tick1(i))) for i in range(int(each[3]) + 1, self.bound + 1): t = [] for j in range(1, i - int(each[3]) + 1): t.append( z3.And( tick2(j), history3(i) - history3(j) == int(each[3]))) self.solver.add(z3.And(tick3(i), z3.Or(t)) == tick1(i)) self.solver.add( z3.ForAll( x, z3.Implies(z3.And(x > 0, x <= self.n + 1), history2(x) >= history1(x)))) self.solver.add( z3.ForAll( x, z3.Implies(z3.And(x > 0, x <= self.n, tick1(x)), tick3(x)))) # self.solver.add( # z3.ForAll(x, z3.Implies( # z3.And(x > 0, x <= history1(self.bound + 1)), # history3(tickStep2(x)) - history3(tickStep1(x)) == int(each[3]) # ))) # for i in range(self.bound + 1): # self.solver.add(history2(i) >= history1(i)) # for i in range(self.bound): # self.solver.add( # z3.Implies( # tick1(i), tick3(i) # ) # ) # for i in range(self.bound + 1): # self.solver.add( # history3(tickStep1(i)) - history3(tickStep2(i)) == int(each[3]) # ) # self.solver.add(z3.ForAll(x, z3.And( # z3.Implies(z3.And(x >= 1, x <= history1(self.bound + 1),tick2(x)), # tick1(tickStep3(history3(x) + int(each[3]))) # )))) else: self.solver.add( z3.ForAll( x, z3.And( z3.Implies(x >= 1, history2(x) >= history1(x))))) self.solver.add( z3.ForAll( x, z3.And( z3.Implies(z3.And(x >= 1, tick1(x)), tick3(x))))) self.solver.add( z3.ForAll( x, z3.And( z3.Implies(x >= 1, (history3(tickStep1(x)) - history3(tickStep2(x)) == int(each[3])))))) elif each[0] == "∝": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] x = z3.Int("x") left = tick1(x) if is_number(each[3]): k = z3.Int("k_%s" % (cnt)) self.solver.add(k >= 0, k < int(each[3])) right = z3.And(tick2(x), history2(x) >= 0, (history2(x) + k) % z3.IntVal(each[3]) == 0) cnt += 1 # right = z3.And(tick2(x), history2(x) > 0, (history2(x)) % z3.IntVal(each[3]) == 0) else: period = z3.Int("%s" % each[3]) tmp = self.parameter[each[3]] self.printParameter[each[3]] = period k = z3.Int("k_%s" % (cnt)) self.solver.add(k >= 0, k < period) right = z3.And(tick2(x), history2(x) >= 0, (history2(x) + k) % period == 0) self.solver.add(period >= int(tmp[2])) self.solver.add(period <= int(tmp[3])) cnt += 1 if self.bound > 0: self.solver.add( z3.ForAll( x, z3.And( z3.Implies(z3.And(x >= 1, x <= self.n), left == right)))) else: self.solver.add( z3.ForAll(x, z3.And(z3.Implies(x >= 1, left == right)))) elif each[0] == "☇": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] tick3 = self.tickDict["t_%s" % (each[3])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] history3 = self.historyDict["h_%s" % (each[3])] self.addTickStep(each[1]) self.addTickStep(each[3]) tickStep1 = self.tickStep["s_%s" % (each[1])] tickStep3 = self.tickStep["s_%s" % (each[3])] x = z3.Int("x") if self.bound > 0: self.solver.add( z3.ForAll( x, z3.Implies( z3.And(x >= 2, x <= history3(self.bound + 1)), tick1(tickStep1(x)) == ( history2(tickStep3(x)) - history2(tickStep3(x - 1)) >= 1)))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 2, z3.And( tick1(tickStep1(x)), history2(tickStep3(x)) - history2(tickStep3(x - 1)) >= 1)))) elif each[0] == "==": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] x = z3.Int("x") if self.bound > 0: self.solver.add( z3.ForAll( x, z3.Implies(z3.And(x >= 1, x <= self.n), tick1(x) == tick2(x)))) else: self.solver.add( z3.ForAll(x, z3.Implies(x >= 1, tick1(x) == tick2(x)))) elif each[0] == "⋈±": tick1 = self.tickDict["t_%s" % (each[1])] tick2 = self.tickDict["t_%s" % (each[2])] history1 = self.historyDict["h_%s" % (each[1])] history2 = self.historyDict["h_%s" % (each[2])] self.addTickStep(each[1]) self.addTickStep(each[2]) tickStep1 = self.tickStep["s_%s" % (each[1])] tickStep2 = self.tickStep["s_%s" % (each[2])] lower = int(each[3]) - int(each[4]) upper = int(each[3]) + int(each[4]) x = z3.Int("x") if self.bound > 0: self.solver.add( z3.ForAll( x, z3.Implies( z3.And(x >= 1, x <= self.bound + 1, tick1(x)), history1(tickStep2(history2(x) + upper)) - history1( tickStep2(history2(x) + lower)) == 1))) self.solver.add( z3.ForAll( x, z3.Implies( z3.And(x >= 2, x <= history1(self.bound + 1)), z3.And( (history2(tickStep1(x)) - history2(tickStep1(x - 1)) >= lower), (history2(tickStep1(x)) - history2(tickStep1(x - 1)) <= upper))))) else: self.solver.add( z3.ForAll( x, z3.Implies( x >= 2, z3.And( (history2(tickStep1(x)) - history2(tickStep1(x - 1)) >= lower), (history2(tickStep1(x)) - history2(tickStep1(x - 1)) <= upper)))))
def generate_assignments(thresh=2, id='karel'): solver = z3.Solver() # declare the SMT variables for the specific code # Block 1 c0 = z3.Int('c0') # repeat (8) c1 = z3.Int('c1') # bool_no_marker (if_else) block_1 = {'b1_1': 'put_marker'} block_1_obj = SMT_Block(block_1, thresh, id=id) values = block_1_obj.block_values block_1_vars = [ele.var for ele in block_1_obj.block_z3_vars ] # for the conditional constraints block_2 = {'b2_1': 'pick_marker'} block_2_obj = SMT_Block(block_2, thresh, id=id) values.extend(block_2_obj.block_values) block_2_vars = [ele.var for ele in block_2_obj.block_z3_vars ] # for the conditional constraints values.append(z3.Or(c0 == 7, c0 == 8, c0 == 9)) values.append(z3.Or(c1 == 10, c1 == 11)) # bool_no_marker, bool_marker block_3 = {'b3_1': 'move'} block_3_obj = SMT_Block(block_3, thresh, id=id) values.extend(block_3_obj.block_values) block_3_vars = [ele.var for ele in block_3_obj.block_z3_vars ] # for the conditional constraints block_4 = {'b4_1': 'phi'} block_4_obj = SMT_Block(block_4, thresh, id=id) values.extend(block_4_obj.block_values) block_4_vars = [ele.var for ele in block_4_obj.block_z3_vars ] # for the conditional constraints block_5 = {'b5_1': 'phi'} block_5_obj = SMT_Block(block_5, thresh, id=id) values.extend(block_5_obj.block_values) block_5_vars = [ele.var for ele in block_5_obj.block_z3_vars ] # for the conditional constraints # all block objects block_objs = [ block_1_obj, block_2_obj, block_3_obj, block_4_obj, block_5_obj ] X = [c0, c1] X.extend([ele.var for ele in block_1_obj.block_z3_vars ]) # added the variables for block 1 X.extend([ele.var for ele in block_2_obj.block_z3_vars ]) # added the variables for block 2 X.extend([ele.var for ele in block_3_obj.block_z3_vars ]) # added the variables for block 3 X.extend([ele.var for ele in block_4_obj.block_z3_vars ]) # added the variables for block 4 X.extend([ele.var for ele in block_5_obj.block_z3_vars ]) # added the variables for block 5 constraints = block_1_obj.block_append_constraints + block_1_obj.flip_turns_constraints + block_1_obj.flip_marker_constraints+ \ block_1_obj.block_elimination_constraints + \ block_2_obj.block_append_constraints + block_2_obj.flip_turns_constraints + \ block_2_obj.flip_marker_constraints+block_2_obj.block_elimination_constraints + \ block_3_obj.block_append_constraints + block_3_obj.flip_turns_constraints + \ block_3_obj.flip_marker_constraints+block_3_obj.block_elimination_constraints + \ block_4_obj.block_append_constraints + block_4_obj.flip_turns_constraints + \ block_4_obj.flip_marker_constraints + block_4_obj.block_elimination_constraints + \ block_5_obj.block_append_constraints + block_5_obj.flip_turns_constraints + \ block_5_obj.flip_marker_constraints + block_5_obj.block_elimination_constraints single_block_change_cons = single_block_change(block_objs) constraints.extend(single_block_change_cons) constraints.extend([ # conditional constraints: if_else(bool_no_marker)---if block constraints z3.Implies(c1 == 11, block_1_vars[0] != 4), z3.Implies( z3.And(c1 == 11, block_1_vars[1] == 4, block_1_vars[0] != 4), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 5)), z3.Implies( z3.And(c1 == 11, block_1_vars[2] == 4, block_1_vars[0] != 4, block_1_vars[1] != 4), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 5, block_1_vars[1] == 1, block_1_vars[1] == 5)), z3.Implies( z3.And(c1 == 11, block_1_vars[3] == 4, block_1_vars[0] != 4, block_1_vars[1] != 4, block_1_vars[2] != 4), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 5, block_1_vars[1] == 1, block_1_vars[1] == 5, block_1_vars[2] == 1, block_1_vars[2] == 5)), z3.Implies( z3.And(c1 == 11, block_1_vars[4] == 4, block_1_vars[0] != 4, block_1_vars[1] != 4, block_1_vars[2] != 4, block_1_vars[3] != 4), z3.And(block_1_vars[0] == 1, block_1_vars[0] == 5, block_1_vars[1] == 1, block_1_vars[1] == 5, block_1_vars[2] == 1, block_1_vars[2] == 5, block_1_vars[3] == 1, block_1_vars[3] == 5)), # else block constraints z3.Implies(c1 == 11, block_2_vars[0] != 5), z3.Implies( z3.And(c1 == 11, block_2_vars[1] == 5, block_2_vars[0] != 5), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 4)), z3.Implies( z3.And(c1 == 11, block_2_vars[2] == 5, block_2_vars[0] != 5, block_2_vars[1] != 5), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 4, block_2_vars[1] == 1, block_2_vars[1] == 4)), z3.Implies( z3.And(c1 == 11, block_2_vars[3] == 5, block_2_vars[0] != 5, block_2_vars[1] != 5, block_2_vars[2] != 5), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 4, block_2_vars[1] == 1, block_2_vars[1] == 4, block_2_vars[2] == 1, block_2_vars[2] == 4)), z3.Implies( z3.And(c1 == 11, block_2_vars[4] == 5, block_2_vars[0] != 5, block_2_vars[1] != 5, block_2_vars[2] != 5, block_2_vars[3] != 5), z3.And(block_2_vars[0] == 1, block_2_vars[0] == 4, block_2_vars[1] == 1, block_2_vars[1] == 4, block_2_vars[2] == 1, block_2_vars[2] == 4, block_2_vars[3] == 1, block_2_vars[3] == 4)), # conditional constraints: if_else(bool_marker)---if block constraints z3.Implies(c1 == 10, block_1_vars[0] != 5), z3.Implies( z3.And(c1 == 10, block_1_vars[1] == 5, block_1_vars[0] != 5), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 4)), z3.Implies( z3.And(c1 == 10, block_1_vars[2] == 5, block_1_vars[0] != 5, block_1_vars[1] != 5), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 4, block_1_vars[1] == 1, block_1_vars[1] == 4)), z3.Implies( z3.And(c1 == 10, block_1_vars[3] == 5, block_1_vars[0] != 5, block_1_vars[1] != 5, block_1_vars[2] != 5), z3.Or(block_1_vars[0] == 1, block_1_vars[0] == 4, block_1_vars[1] == 1, block_1_vars[1] == 4, block_1_vars[2] == 1, block_1_vars[2] == 4)), z3.Implies( z3.And(c1 == 10, block_1_vars[4] == 5, block_1_vars[0] != 5, block_1_vars[1] != 5, block_1_vars[2] != 5, block_1_vars[3] != 5), z3.And(block_1_vars[0] == 1, block_1_vars[0] == 4, block_1_vars[1] == 1, block_1_vars[1] == 4, block_1_vars[2] == 1, block_1_vars[2] == 4, block_1_vars[3] == 1, block_1_vars[3] == 4)), # else block constraints z3.Implies(c1 == 10, block_2_vars[0] != 4), z3.Implies( z3.And(c1 == 10, block_2_vars[1] == 4, block_2_vars[0] != 4), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 5)), z3.Implies( z3.And(c1 == 10, block_2_vars[2] == 4, block_2_vars[0] != 4, block_2_vars[1] != 4), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 5, block_2_vars[1] == 1, block_2_vars[1] == 5)), z3.Implies( z3.And(c1 == 10, block_2_vars[3] == 4, block_2_vars[0] != 4, block_2_vars[1] != 4, block_2_vars[2] != 4), z3.Or(block_2_vars[0] == 1, block_2_vars[0] == 5, block_2_vars[1] == 1, block_2_vars[1] == 5, block_2_vars[2] == 1, block_2_vars[2] == 5)), z3.Implies( z3.And(c1 == 10, block_2_vars[4] == 4, block_2_vars[0] != 4, block_2_vars[1] != 4, block_2_vars[2] != 4, block_2_vars[3] != 4), z3.And(block_2_vars[0] == 1, block_2_vars[0] == 5, block_2_vars[1] == 1, block_2_vars[1] == 5, block_2_vars[2] == 1, block_2_vars[2] == 5, block_2_vars[3] == 1, block_2_vars[3] == 5)), ]) unequal_blocks_con = block_unequal_constraint(block_1_obj, block_2_obj) constraints.extend(unequal_blocks_con) # add the values and the constraints solver.add(values + constraints) # generate all the assignments models = gen_all(solver, X) assignments = [] for model in models: a = [ str(model[c0].as_long()), type_to_str[ConditionalType(model[c1].as_long())] ] a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_1_vars ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_2_vars ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_3_vars ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_4_vars ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_5_vars ]) assignments.append(a) #print(a) #print('Found #{} SAT values'.format(len(models))) return assignments
def generate_assignments(thresh=2): solver = z3.Solver() # declare the SMT variables for the specific code # Block 1 block_1 = {'b1_1': 'move'} block_1_obj = SMT_Block(block_1, thresh) values = block_1_obj.block_values block_1_vars = [ele.var for ele in block_1_obj.block_z3_vars ] # for the conditional constraints c1 = z3.Int('c1') # bool_path_ahead (if_else) block_2 = {'b2_1': 'turn_left'} block_2_obj = SMT_Block(block_2, thresh) values.extend(block_2_obj.block_values) block_2_vars = [ele.var for ele in block_2_obj.block_z3_vars ] # for the conditional constraints values.append(c1 == 7) # same conditional value block_3 = {'b3_1': 'phi'} block_3_obj = SMT_Block(block_3, thresh) values.extend(block_3_obj.block_values) block_3_vars = [ele.var for ele in block_3_obj.block_z3_vars ] # for the conditional constraints # all block objects block_objs = [block_1_obj, block_2_obj, block_3_obj] X = [c1] X.extend([ele.var for ele in block_1_obj.block_z3_vars ]) # added the variables for block 1 X.extend([ele.var for ele in block_2_obj.block_z3_vars ]) # added the variables for block 2 X.extend([ele.var for ele in block_3_obj.block_z3_vars ]) # added the variables for block 2 constraints = block_1_obj.block_append_constraints + block_1_obj.flip_turns_constraints + block_1_obj.block_elimination_constraints + \ block_2_obj.block_append_constraints + block_2_obj.flip_turns_constraints + block_2_obj.block_elimination_constraints + \ block_3_obj.block_append_constraints + block_3_obj.flip_turns_constraints + block_3_obj.block_elimination_constraints single_block_change_cons = single_block_change(block_objs) constraints.extend(single_block_change_cons) constraints.extend([ # conditional constraints: if_else(bool_path_ahead)---if block constraints z3.Implies( c1 == 7, z3.Or( block_1_vars[0] == 1, block_1_vars[1] == 1, block_1_vars[2] == 1, block_1_vars[3] == 1, block_1_vars[4] == 1, )), z3.Implies(z3.And(c1 == 7, block_1_vars[1] == 1, block_1_vars[0] != 1), z3.And(block_1_vars[0] != 2, block_1_vars[0] != 3)), z3.Implies( z3.And(c1 == 7, block_1_vars[2] == 1, block_1_vars[0] != 1, block_1_vars[1] != 1), z3.And(block_1_vars[0] != 2, block_1_vars[0] != 3, block_1_vars[1] != 2, block_1_vars[1] != 3)), z3.Implies( z3.And(c1 == 7, block_1_vars[3] == 1, block_1_vars[0] != 1, block_1_vars[1] != 1, block_1_vars[2] != 1), z3.And(block_1_vars[0] != 2, block_1_vars[0] != 3, block_1_vars[1] != 2, block_1_vars[1] != 3, block_1_vars[2] != 2, block_1_vars[2] != 3)), z3.Implies( z3.And(c1 == 7, block_1_vars[4] == 1, block_1_vars[0] != 1, block_1_vars[1] != 1, block_1_vars[2] != 1, block_1_vars[3] != 1), z3.And(block_1_vars[0] != 2, block_1_vars[0] != 3, block_1_vars[1] != 2, block_1_vars[1] != 3, block_1_vars[2] != 2, block_1_vars[2] != 3, block_1_vars[3] != 2, block_1_vars[3] != 3)), # else block constraints z3.Implies(c1 == 7, block_2_vars[0] != 1), z3.Implies(z3.And(c1 == 7, block_2_vars[1] == 1, block_2_vars[0] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[2] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[3] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3)), z3.Implies( z3.And(c1 == 7, block_2_vars[4] == 1, block_2_vars[0] != 1, block_2_vars[1] != 1, block_2_vars[2] != 1, block_2_vars[3] != 1), z3.Or(block_2_vars[0] == 2, block_2_vars[0] == 3, block_2_vars[1] == 2, block_2_vars[1] == 3, block_2_vars[2] == 2, block_2_vars[2] == 3, block_2_vars[3] == 2, block_2_vars[3] == 3)), ]) unequal_blocks_con = block_unequal_constraint(block_1_obj, block_2_obj) constraints.extend(unequal_blocks_con) # add the values and the constraints solver.add(values + constraints) # generate all the assignments models = gen_all(solver, X) assignments = [] for model in models: a = [ 'repeat_until_goal(bool_goal)', type_to_str[ConditionalType(model[c1].as_long())] ] a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in X[1:block_1_obj.size + 1] ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in X[block_1_obj.size + 1:block_2_obj.size + block_1_obj.size + 1] ]) a.extend([ type_to_str[VariableType(model[ele].as_long())] for ele in block_3_vars ]) assignments.append(a) #print(a) #print('Found #{} SAT values'.format(len(models))) return assignments
class Z3Context(Context): def __init__(self, *args, **kw): Context.__init__(self, *args, **kw) self.solver = z3.Solver() def __getitem__(self, key): if not isinstance(key, Sort) and key in self.storage: return self.storage[key] elif isinstance(key, Sort): if key.name in self.storage: return self.storage[key.name] val = self.new_from_sort(key) self.storage[key.name] = val return val else: raise ValueError("%s not found! %s. %s." %(key, type(key), self.storage)) def new_from_sort(self, key): if isinstance(key, Bool): key = key.name val = z3.Bool(key) return val elif isinstance(key, Int): key = key.name val = z3.Int(key) return val elif isinstance(key, String): key = key.name val = z3.String(key) return val elif isinstance(key, BitVec): name = key.name size = key.size val = z3.BitVec(name, size) return val raise TypeError("%s not supported!" %type(key)) def s_assert(self, expr): self.solver.assert_exprs(expr.cval(self)) def s_check(self): res = self.solver.check() return res def s_model(self): try: m = self.solver.model() return self.process_model(m) except z3.Z3Exception: return {} def s_push(self): self.solver.push() def s_pop(self): self.solver.pop() def s_reset(self): self.solver.reset() def solve(self, AST): outputs = [] self.s_reset() for node in AST: if isinstance(node, Sort): self.s_assert(node) elif isinstance(node, Let): self.s_assert(node.term) elif isinstance(node, Command): if node.cname == "push": self.s_push() elif node.cname == "pop": self.s_pop() elif node.cname == "check-sat": logger.info("\n-------") outputs.append(self.s_check()) logger.info("Check: %s" % outputs[-1]) elif node.cname == "get-model": outputs.append(self.s_model()) logger.info("Model: %s" % outputs[-1]) else: raise ValueError("Command %s not supported!" %node) return outputs def process_model(self, z3_model): m = {} for v in z3_model: m[v.name()] = self.get_py_value(z3_model.get_interp(v)) return m def get_py_value(self, assignment): if z3.is_ast(assignment): if z3.is_int_value(assignment): return assignment.as_long() if z3.is_bool(assignment): return z3.is_true(assignment) if z3.is_string_value(assignment): try: val = assignment.as_string()[1:-1] # remove quotes val = val.replace("\\x00", "") return str(val) # Z3 throws encoding errors. It can't decode its own solution.. # TODO find a better fix. except UnicodeDecodeError: val = assignment.as_ast() return repr(val) raise ValueError("Unsupported Z3 type! %s" % type(assignment)) return assignment BoolVal = lambda self, x : z3.BoolVal(x) StringVal = lambda self, x : z3.StringVal(x) IntVal = lambda self, x : z3.IntVal(x) BitVecVal = lambda self, val, size : z3.BitVecVal(val, size) And = lambda self, *x : z3.And(x) Or = lambda self, *x : z3.Or(x) Xor = lambda self, *x : reduce(xor, x) Implies = lambda self, x, y : z3.Implies(x, y) Distinct = lambda self, x, y : z3.Distinct(x, y) def Eq(self, x, y): # x = z3.String("x") # x == "test" #throws an error. This is a workaround for now. x = z3.StringVal(x) if isinstance(x,str) else x y = z3.StringVal(y) if isinstance(y,str) else y return eq(x,y) Not = lambda self, x : z3.Not(x) If = lambda self, *x : z3.If(*x) add = lambda self, *x : reduce(add, x) sub = lambda self, *x : reduce(sub, x) if len(x) > 1 else -x[0] mul = lambda self, *x : reduce(mul, x) lt = lambda self, *x : reduce(lt, x) le = lambda self, *x : reduce(le, x) gt = lambda self, *x : reduce(gt, x) ge = lambda self, *x : reduce(ge, x) concat = lambda self, *x : reduce(add, x) length = lambda self, x : z3.Length(x) contains = lambda self, x, y : z3.Contains(x, y) indexof = lambda self, x, y, z=0 : z3.IndexOf(x, y, z) extract = lambda self, x, y, z : z3.Extract(x, y, z) bvadd = add bvsub = sub bvmul = mul bvxor = Xor bvneg = lambda self, x : neg(x) bvnot = lambda self, x : inv(x) bvconcat = lambda self, *x : z3.Concat(*x) bvlshr = lambda self, x, y : z3.LShR(x, y) bvlshl = lambda self, x, y : z3.LShL(x, y) bvuge = lambda self, x, y : z3.UGE(x, y) bvurem = lambda self, x, y : z3.URem(x, y) # TODO Need to define all these with stuff in computation folder FPAbs = lambda self, *x : None FPNeg = lambda self, *x : None FPAdd = lambda self, *x : None FPSub = lambda self, *x : None FPMul = lambda self, *x : None FPDiv = lambda self, *x : None FPFMA = lambda self, *x : None FPRem = lambda self, *x : None FPSqrt = lambda self, *x : None FPRoundToIntegral = lambda self, *x : None FPMin = lambda self, *x : None FPMax = lambda self, *x : None FPLEQ = lambda self, *x : None FPLT = lambda self, *x : None FPGEQ = lambda self, *x : None FPGT = lambda self, *x : None FPEQ = lambda self, *x : None FPIsNormal = lambda self, *x : None FPIsSubNormal = lambda self, *x : None FPIsZero = lambda self, *x : None FPIsInfinite = lambda self, *x : None FPIsNan = lambda self, *x : None FPIsNegative = lambda self, *x : None FPIsPositive = lambda self, *x : None