Vector's cross product and if statement in function - python

My program is working but not all of it's parts, I listed my problems in comment of program
class MyVector:
def __init__(self, vector):
self.vector = vector
def get_vector(self):
return self.vector
def __mul__(self, other):
scalar_result = 0 # or 0.0
for i in range(0, len(self.vector)):
scalar_result += self.vector[i] * other.vector[i]
return scalar_result
def is_perpendicular_to(self, other): #is there a way that I could make function which will print wheter they are perpendicular or not?
if (scalar_result == 0): #this isn't seem to work
print("They are perpendicular")
"""
Also I was hoping that I can get crossdot product of these two vectors, but I can not make it functional
def crossProd(vector):
dimension = len(a)
c = []
for i in range(dimension):
c.append(0)
for j in range(dimension):
if j <> i:
for k in range(dimension):
if k <> i:
if k > j:
c[i] += a[j] * b[k]
elif k < j:
c[i] -= a[j] * b[k]
return c
"""
if __name__ == "__main__":
vec1 = MyVector([1, 0, 3, 0])
vec2 = MyVector([0, 4, 0, 4])
print(vec1.get_vector())
print(vec2.get_vector())
scalar_result = vec1 * vec2
print(scalar_result)
In the upper part I created logical algorithm that I think should work, but I can't put it to the program, for me it is not functional

Related

Solving 2D maze, how to avoid runtime error for hidden test case?

There are two test cases with this problem, the first test case is shown below and the second is a hidden test case that I still can't access. The first test case works perfectly however the second test case is showing me a runtime error. I am not sure how to proceed from here.
Help Donkey find refuge in the swamp. Unfortunately for him, Shrek’s swamp is a bit of a MAZE, and we need to help him find his way to Shrek’s hut. Donkey can only move up, down, right, and left, and he can only travel on dirt and lily pads.
Input Format
The first line will contain a single integer n that indicates the number of data sets that follow. Each data set will start with two integers, r and c, denoting the number of rows and columns in the maze. The following r rows will contain c characters: o – represents a Lily Pad . – represents dirt. W – represents water, Donkey cannot walk on these T – represents a tree, Donkey cannot walk on these M – represents mud, Donkey cannot walk on these D – represents Donkey’s current location, or the starting point of the maze. S – represents Shrek’s hut, or the end point of the maze.
Constraints
None.
Output Format
The output should be “We Making Waffles!!”, if it is possible for Donkey to make it to Shrek’s swamp, and “Silence is a friend that never betrays”, is it is not possible.
Sample Input 0
2
5 5
D..T.
.WoWW
.WooW
MMM.T
MMM.S
5 5
DTT..
...MM
WWMMM
WWMMM
TSMMM
Sample Output 0
We Making Waffles!!
Silence is a friend that never betrays
This is my code
import collections
for i in range(int(input())):
wall, clear, goal = 1, 0, 'S'
width,height=map(int,input().split())
def bfs(maze, start):
queue = collections.deque()
queue.append(start)
seen = set([start])
while queue:
path = queue.popleft()
x, y = path
if maze[y][x] == goal:
return True
for x2, y2 in ((x+1,y), (x-1,y), (x,y+1), (x,y-1)):
if ( 0 <= x2 < width and
0 <= y2 < height and
maze[y2][x2] != wall and
(x2, y2) not in seen):
queue.append( (x2, y2))
seen.add((x2, y2))
return False
mat=[]
for i in range(width):
mat.append(list(str(input())))
def change(lol):
for index,item in enumerate(lol):
if isinstance(item, list):
change(item)
if item=='.':
lol[index] = 0
elif item=='o':
lol[index] = 0
elif item=='W':
lol[index]= 1
elif item== 'M':
lol[index]=1
elif item== 'T':
lol[index] =1
return lol
change(mat)
def find(matrix, item):
for i in range(len(matrix)):
try:
j = matrix[i].index(item)
return (i, j)
except ValueError:
pass
start=(find(mat,'D'))
end=(find(mat,'S'))
mat[start[0]][start[1]]= 0
final=(bfs(mat,(start)))
if final== True:
print("We Making Waffles!!")
else:
print("Silence is a friend that never betrays")
Because of the hidden test case, I am not sure what caused the runtime error, especially with the first testcase running perfectly fine.
I was able to fix the runtime error! Here is my solution to help other people:
import sys
def isSafe(mat, visited, x, y):
return 0 <= x < len(mat) and 0 <= y < len(mat[0]) and \
not (mat[x][y] == 0 or visited[x][y])
def findShortestPath(mat, visited, i, j, dest, min_dist=sys.maxsize, dist=0):
if (i, j) == dest:
return min(dist, min_dist)
visited[i][j] = 1
if isSafe(mat, visited, i + 1, j):
min_dist = findShortestPath(mat, visited, i + 1, j, dest, min_dist, dist + 1)
if isSafe(mat, visited, i, j + 1):
min_dist = findShortestPath(mat, visited, i, j + 1, dest, min_dist, dist + 1)
if isSafe(mat, visited, i - 1, j):
min_dist = findShortestPath(mat, visited, i - 1, j, dest, min_dist, dist + 1)
if isSafe(mat, visited, i, j - 1):
min_dist = findShortestPath(mat, visited, i, j - 1, dest, min_dist, dist + 1)
visited[i][j] = 0
return min_dist
def findShortestPathLength(mat, src, dest):
i, j = src
x, y = dest
if not mat or len(mat) == 0 or mat[i][j] == 0 or mat[x][y] == 0:
return -1
(M, N) = (len(mat), len(mat[0]))
visited = [[False for _ in range(N)] for _ in range(M)]
min_dist = findShortestPath(mat, visited, i, j, dest)
if min_dist != sys.maxsize:
return min_dist
else:
return -1
def change(lol):
for index,item in enumerate(lol):
if isinstance(item, list):
change(item)
if item=='.':
lol[index] = 1
elif item=='o':
lol[index] = 1
elif item=='W':
lol[index]= 0
elif item== 'M':
lol[index]=0
elif item== 'T':
lol[index] =0
return lol
def find(matrix, item):
for i in range(len(matrix)):
try:
j = matrix[i].index(item)
return (i, j)
except ValueError:
pass
if __name__ == '__main__':
for i in range(int(input())):
nums= input().split()
nums= list(map(int,nums))
mat=[]
for i in range(nums[0]):
mat.append(list(str(input())))
change(mat)
src=(find(mat,'D'))
dest=(find(mat,'S'))
mat[src[0]][src[1]]= 1
mat[dest[0]][dest[1]]=1
min_dist = findShortestPathLength(mat, src, dest)
if min_dist != -1:
print("We Making Waffles!!")
else:
print("Silence is a friend that never betrays")")

How to uniquely Identify objects in Python so that we can Insert Nodes in a Queue?

Currently I was trying to solve the 8 Tile Problem using the A* Algorithm, the heuristic function was the number of inversions in the Matrix provided, As I am adding the Nodes and their states to a queue I need to be able to uniquely identify them for this purpose I am using the __eq__() function in the Node Class.
However the program seems to not be able to separate two similar instances and enters into an infinite loop.
The central issue according to me is the fact that I am not able to correctly identify the values and see the difference between them.
I am using a queue instead of a pq as I am new to them currently.
So could you please help me understand where I am going wrong.
import random
cols = 3;
rows = 3;
l = [i for i in range(9)];
random.shuffle(l);
initial = [[0 for i in range(cols)] for j in range(rows)];
k = 0;
for i in range(3):
for j in range(3):
initial[i][j] = l[k];
k += 1;
print(initial);
arr = [[0 for i in range(cols)] for j in range(rows)]
for i in range(3):
for j in range(3):
arr[i][j] = 3*i + j;
class Node:
def __init__(self,s,p,d):
self.state = s.copy();
self.parent = p;
self.g = 0;
self.isDummy = d;
if(p is not None):
self.g = p.g + 1;
def __eq__(self,other):
l = self.state.copy()
k= other.state.copy()
for i in range(3):
for j in range(3):
if(l[i][j] != k[i][j]):
return False;
return True;
def checkInversion(self):
invert = 0;
l = [];
for i in range(3):
for j in range(3):
l.append(self.state[i][j]);
for i in range(len(l)):
for j in range(i+1,len(l)):
if(l[j] != 0 and l[i] > l[j]):
invert += 1;
return invert;
def isViable(self):
return self.checkInversion()%2 == 0;
def createChild(self,move1,move2,index):
x = 0;
y = 0;
global rows;
global cols;
l = self.state.copy()
for i in range(3):
for j in range(3):
if(l[i][j] == 0):
x = i;
y = j;
j = x + move1[index];
k = y + move2[index];
lis = [[0 for i in range(cols)] for j in range(rows)];
for i in range(3):
for j in range(3):
lis[i][j] = self.state[i][j];
if(j < 0 or j > 2):
return Node(lis,self,True);
if (k < 0 or k > 2):
return Node(lis,self,True);
temp = lis[x][y];
lis[x][y] = lis[j][k];
lis[j][k] = temp;
return Node(lis,self,False);
def h(self):
return self.checkInversion();
def f(self):
return self.g + self.h();
def isGoal(self):
global Goal
if(self.state == Goal.state):
return True;
return False;
def checkExplored(self,l):
n = len(l);
for i in range(n):
if(l[i] == self):
return False;
return True;
def show(self):
print(self.state);
Goal = Node(arr,None,False);
def AStar(source):
if(source.isGoal()):
return True;
q = [];
move1 = [1,0,-1,0];
move2 = [0,1,0,-1];
q.append(source);
explored = [];
while(q):
cur = q[0];
mi = 0;
for i in range(len(q)):
if(q[i].f() < cur.f()):
cur = q[i];
mi = i;
a = q.pop(mi);
a.show();
if(a.isGoal()):
return a;
explored.append(a);
for i in range(4):
child = a.createChild(move1,move2,i);
if(child.isDummy):
continue;
flag = False;
flag2 = False;
for j in range(len(explored)):
if(child == explored[j]):
flag2 = True;
if(not flag2):
for j in range(len(q)):
if(child == q[j]):
flag = True;
if(child.g < q[j].g):
q[j].g = child.g;
if(not flag):
q.append(child);
k = Node(initial,None,False);
#print(k.isGoal());
print(k.checkInversion());
a = Node(initial,None,False);
if(k.checkInversion()%2 == 0):
a = AStar(k);
#print(a);
a.show()
enter code here

How can I implement IDA* algorithm in Python for 15-Puzzle problem?

I'm trying to solve the 15-Puzzle problem using IDA* algorithm and Manhattan heuristic.
I already implemented the algorithm from the pseudocode in this Wikipedia page (link).
Here's my code so far :
def IDA(initial_state, goal_state):
initial_node = Node(initial_state)
goal_node = Node(goal_state)
threshold = manhattan_heuristic(initial_state, goal_state)
path = [initial_node]
while 1:
tmp = search(path, goal_state, 0, threshold)
if tmp == True:
return path, threshold
elif tmp == float('inf'):
return False
else:
threshold = tmp
def search(path, goal_state, g, threshold):
node = path[-1]
f = g + manhattan_heuristic(node.state, goal_state)
if f > threshold:
return f
if np.array_equal(node.state, goal_state):
return True
minimum = float('inf')
for n in node.nextnodes():
if n not in path:
path.append(n)
tmp = search(path, goal_state, g + 1, threshold)
if tmp == True:
return True
if tmp < minimum:
minimum = tmp
path.pop()
return minimum
def manhattan_heuristic(state1, state2):
size = range(1, len(state1) ** 2)
distances = [count_distance(num, state1, state2) for num in size]
return sum(distances)
def count_distance(number, state1, state2):
position1 = np.where(state1 == number)
position2 = np.where(state2 == number)
return manhattan_distance(position1, position2)
def manhattan_distance(a, b):
return abs(b[0] - a[0]) + abs(b[1] - a[1])
class Node():
def __init__(self, state):
self.state = state
def nextnodes(self):
zero = np.where(self.state == 0)
y,x = zero
y = int(y)
x = int(x)
up = (y - 1, x)
down = (y + 1, x)
right = (y, x + 1)
left = (y, x - 1)
arr = []
for direction in (up, down, right, left):
if len(self.state) - 1 >= direction[0] >= 0 and len(self.state) - 1 >= direction[1] >= 0:
tmp = np.copy(self.state)
tmp[direction[0], direction[1]], tmp[zero] = tmp[zero], tmp[direction[0], direction[1]]
arr.append(Node(tmp))
return arr
I'm testing this code with a 3x3 Puzzle and here's the infinite loop! Due to the recursion I have some trouble testing my code...
I think the error might be here : tmp = search(path, goal_state, g + 1, threshold) (in the search function). I'm adding only one to the g cost value. It should be correct though, because I can only move a tile 1 place away.
Here's how to call the IDA() function:
initial_state = np.array([8 7 3],[4 1 2],[0 5 6])
goal_state = np.array([1 2 3],[8 0 4],[7 6 5])
IDA(initial_state, goal_state)
Can someone help me on this ?
There are couple of issues in your IDA* implementation. First, what is the purpose of the variable path? I found two purposes of path in your code:
Use as a flag/map to keep the board-states that is already been visited.
Use as a stack to manage recursion states.
But, it is not possible to do both of them by using a single data structure. So, the first modification that your code requires:
Fix-1: Pass current node as a parameter to the search method.
Fix-2: flag should be a data structure that can perform a not in query efficiently.
Now, fix-1 is easy as we can just pass the current visiting node as the parameter in the search method. For fix-2, we need to change the type of flag from list to set as:
list's average case complexity for x in s is: O(n)
set's
Average case complexity for x in s is: O(1)
Worst case complexity for x in s is: O(n)
You can check more details about performance for testing memberships: list vs sets for more details.
Now, to keep the Node information into a set, you need to implement __eq__ and __hash__ in your Node class. In the following, I have attached the modified code.
import timeit
import numpy as np
def IDA(initial_state, goal_state):
initial_node = Node(initial_state)
goal_node = Node(goal_state)
threshold = manhattan_heuristic(initial_state, goal_state)
#print("heuristic threshold: {}".format(threshold))
loop_counter = 0
while 1:
path = set([initial_node])
tmp = search(initial_node, goal_state, 0, threshold, path)
#print("tmp: {}".format(tmp))
if tmp == True:
return True, threshold
elif tmp == float('inf'):
return False, float('inf')
else:
threshold = tmp
def search(node, goal_state, g, threshold, path):
#print("node-state: {}".format(node.state))
f = g + manhattan_heuristic(node.state, goal_state)
if f > threshold:
return f
if np.array_equal(node.state, goal_state):
return True
minimum = float('inf')
for n in node.nextnodes():
if n not in path:
path.add(n)
tmp = search(n, goal_state, g + 1, threshold, path)
if tmp == True:
return True
if tmp < minimum:
minimum = tmp
return minimum
def manhattan_heuristic(state1, state2):
size = range(1, len(state1) ** 2)
distances = [count_distance(num, state1, state2) for num in size]
return sum(distances)
def count_distance(number, state1, state2):
position1 = np.where(state1 == number)
position2 = np.where(state2 == number)
return manhattan_distance(position1, position2)
def manhattan_distance(a, b):
return abs(b[0] - a[0]) + abs(b[1] - a[1])
class Node():
def __init__(self, state):
self.state = state
def __repr__(self):
return np.array_str(self.state.flatten())
def __hash__(self):
return hash(self.__repr__())
def __eq__(self, other):
return self.__hash__() == other.__hash__()
def nextnodes(self):
zero = np.where(self.state == 0)
y,x = zero
y = int(y)
x = int(x)
up = (y - 1, x)
down = (y + 1, x)
right = (y, x + 1)
left = (y, x - 1)
arr = []
for direction in (up, down, right, left):
if len(self.state) - 1 >= direction[0] >= 0 and len(self.state) - 1 >= direction[1] >= 0:
tmp = np.copy(self.state)
tmp[direction[0], direction[1]], tmp[zero] = tmp[zero], tmp[direction[0], direction[1]]
arr.append(Node(tmp))
return arr
initial_state = np.array([[8, 7, 3],[4, 1, 2],[0, 5, 6]])
goal_state = np.array([[1, 2, 3],[8, 0, 4],[7, 6, 5]])
start = timeit.default_timer()
is_found, th = IDA(initial_state, goal_state)
stop = timeit.default_timer()
print('Time: {} seconds'.format(stop - start))
if is_found is True:
print("Solution found with heuristic-upperbound: {}".format(th))
else:
print("Solution not found!")
Node: Please double check your Node.nextnodes() and manhattan_heuristic() methods as I did not pay much attention in those areas. You can check this GitHub repository for other algorithmic implementations (i.e., A*, IDS, DLS) to solve this problem.
References:
Python Wiki: Time Complexity
TechnoBeans: Performance for testing memberships: list vs tuples vs sets
GitHub: Puzzle Solver (by using problem solving techniques)

Bad performance of sorting algorithms implemented

I have implemented some sorting algorithms including Insertion, Selection, Shell, two kinds of Merge. I found that the performance of my implements didn't accord with the description of Algorithms(4th).
For example, here are two kinds of Merge sorting. When sorting a list contains 100,000 elements, Merge1 takes about 0.6s, and Merge2 takes about 50+s. But Merge2 is almost the same as the one in Algorithms(4th) except I use python. I can't figure it out why Merge2 is so slow and how to improve it. Can somebody help me? Thanks!
class Merge1:
def merge(self, a, b):
i = 0; j = 0
res = []
while i < len(a) and j < len(b):
if a[i] < b[j]:
res.append(a[i])
i = i + 1
else:
res.append(b[j])
j = j + 1
res = res + a[i:] + b[j:]
return res
def sort(self, source):
if len(source) <= 1:
return source
half = len(source) // 2
left = self.sort(source[:half])
right = self.sort(source[half:])
retval = self.merge(left, right)
return retval
def is_sort(self, source):
length = len(source)
for i in range(0, length-1):
if source[i] > source[i+1]:
return False
return True
class Merge2:
def merge(self, source, lo, mid ,hi):
i = lo
j = mid + 1
aux = source[:]
k = lo
while k <= hi:
if i > mid:
source[k] = aux[j]
j = j + 1
elif j > hi:
source[k] = aux[i]
i = i + 1
elif aux[i] < aux[j]:
source[k] = aux[i]
i = i + 1
else:
source[k] = aux[j]
j = j + 1
k = k+1
def sort(self, source):
sz = 1
N = len(source)
while sz < N:
for lo in range(0, N-sz, sz+sz):
# pdb.set_trace()
self.merge(source, lo, lo+sz-1, min(lo+sz+sz-1, N-1))
sz = sz + sz
def is_sort(self, source):
length = len(source)
for i in range(0, length-1):
if source[i] > source[i+1]:
return False
return True
Here is the implement in Algorithms:
Here is the test code:
merge1 = Merge1()
source = np.random.randint(100000, size=100000).tolist()
start = time.time()
merge1.sort(source)
end = time.time()
print("Merge1 takes: {}s".format(end-start))
merge2 = Merge2()
source = np.random.randint(100000, size=100000).tolist()
start = time.time()
merge2.sort(source)
end = time.time()
print("Merge2 takes: {}s".format(end-start))
result:
E:>python sort.py
Merge1 takes: 0.6376256942749023s
Merge2 takes: 57.99568271636963s
Consider this modification. According to my quick tests, it improved the performance considerably (from nearly one minute down to less than 1 second). The main performance gain comes from avoiding to create that many copies of the whole list. The other alterations only increase performance marginally.
According to a simple comparison of the sum it should not mess up the list, but you should do some more tests if you like to use it.
class Merge4:
def merge(self, source, aux, lo, mid ,hi):
i = lo
j = mid + 1
a_j= aux[j]
a_i= aux[i]
k = lo
while k <= hi:
if i > mid:
source[k] = a_j
j += 1
a_j= aux[j]
elif j > hi:
source[k] = a_i
i += 1
a_i= aux[i]
elif a_i < a_j:
source[k] = a_i
i += 1
a_i= aux[i]
else:
source[k] = a_j
j += 1
a_j= aux[j]
k += 1
# update the aux array for the next call
aux[lo:hi+1]= source[lo:hi+1]
def sort(self, source):
sz = 1
N = len(source)
while sz < N:
sz_2= sz * 2
# create the aux array, that will be maintained continuously
# and add one extra None, so the "prefetching" works also
# during the last iteration (refering to a_i and a_j)
aux= source[:]
aux.append(None)
for lo in range(0, N-sz, sz_2):
# pdb.set_trace()
self.merge(source, aux, lo, lo+sz-1, min(lo+sz_2-1, N-1))
sz = sz_2
def is_sort(self, source):
length = len(source)
for i in range(0, length-1):
if source[i] > source[i+1]:
return False
return True

(Z3Py) checking all solutions for equation

In Z3Py, how can I check if equation for given constraints have only one solution?
If more than one solution, how can I enumerate them?
You can do that by adding a new constraint that blocks the model returned by Z3.
For example, suppose that in the model returned by Z3 we have that x = 0 and y = 1. Then, we can block this model by adding the constraint Or(x != 0, y != 1).
The following script does the trick.
You can try it online at: http://rise4fun.com/Z3Py/4blB
Note that the following script has a couple of limitations. The input formula cannot include uninterpreted functions, arrays or uninterpreted sorts.
from z3 import *
# Return the first "M" models of formula list of formulas F
def get_models(F, M):
result = []
s = Solver()
s.add(F)
while len(result) < M and s.check() == sat:
m = s.model()
result.append(m)
# Create a new constraint the blocks the current model
block = []
for d in m:
# d is a declaration
if d.arity() > 0:
raise Z3Exception("uninterpreted functions are not supported")
# create a constant from declaration
c = d()
if is_array(c) or c.sort().kind() == Z3_UNINTERPRETED_SORT:
raise Z3Exception("arrays and uninterpreted sorts are not supported")
block.append(c != m[d])
s.add(Or(block))
return result
# Return True if F has exactly one model.
def exactly_one_model(F):
return len(get_models(F, 2)) == 1
x, y = Ints('x y')
s = Solver()
F = [x >= 0, x <= 1, y >= 0, y <= 2, y == 2*x]
print get_models(F, 10)
print exactly_one_model(F)
print exactly_one_model([x >= 0, x <= 1, y >= 0, y <= 2, 2*y == x])
# Demonstrate unsupported features
try:
a = Array('a', IntSort(), IntSort())
b = Array('b', IntSort(), IntSort())
print get_models(a==b, 10)
except Z3Exception as ex:
print "Error: ", ex
try:
f = Function('f', IntSort(), IntSort())
print get_models(f(x) == x, 10)
except Z3Exception as ex:
print "Error: ", ex
The python function below is a generator of models for formulas that contain both constants and functions.
import itertools
from z3 import *
def models(formula, max=10):
" a generator of up to max models "
solver = Solver()
solver.add(formula)
count = 0
while count<max or max==0:
count += 1
if solver.check() == sat:
model = solver.model()
yield model
# exclude this model
block = []
for z3_decl in model: # FuncDeclRef
arg_domains = []
for i in range(z3_decl.arity()):
domain, arg_domain = z3_decl.domain(i), []
for j in range(domain.num_constructors()):
arg_domain.append( domain.constructor(j) () )
arg_domains.append(arg_domain)
for args in itertools.product(*arg_domains):
block.append(z3_decl(*args) != model.eval(z3_decl(*args)))
solver.add(Or(block))
x, y = Ints('x y')
F = [x >= 0, x <= 1, y >= 0, y <= 2, y == 2*x]
for m in models(F):
print(m)
Referencing http://theory.stanford.edu/~nikolaj/programmingz3.html#sec-blocking-evaluations
def all_smt(s, initial_terms):
def block_term(s, m, t):
s.add(t != m.eval(t))
def fix_term(s, m, t):
s.add(t == m.eval(t))
def all_smt_rec(terms):
if sat == s.check():
m = s.model()
yield m
for i in range(len(terms)):
s.push()
block_term(s, m, terms[i])
for j in range(i):
fix_term(s, m, terms[j])
yield from all_smt_rec(terms[i:])
s.pop()
yield from all_smt_rec(list(initial_terms))
This indeed performs quite better from Leonardo's own answer (considering his answer is quite old)
start_time = time.time()
v = [BitVec(f'v{i}',3) for i in range(6)]
models = get_models([Sum(v)==0],8**5)
print(time.time()-start_time)
#211.6482105255127s
start_time = time.time()
s = Solver()
v = [BitVec(f'v{i}',3) for i in range(6)]
s.add(Sum(v)==0)
models = list(all_smt(s,v))
print(time.time()-start_time)
#13.375828742980957s
Splitting the search space into disjoint models creates a huge difference as far as I have observed
The answer given by Himanshu Sheoran cites the paper https://theory.stanford.edu/%7Enikolaj/programmingz3.html#sec-blocking-evaluations
Unfortunately there was a bug in the implementation given in the paper at that time which was quoted in that answer. The function has since been corrected.
For posterity, here's the correct version of the code:
def all_smt(s, initial_terms):
def block_term(s, m, t):
s.add(t != m.eval(t, model_completion=True))
def fix_term(s, m, t):
s.add(t == m.eval(t, model_completion=True))
def all_smt_rec(terms):
if sat == s.check():
m = s.model()
yield m
for i in range(len(terms)):
s.push()
block_term(s, m, terms[i])
for j in range(i):
fix_term(s, m, terms[j])
yield from all_smt_rec(terms[i:])
s.pop()
yield from all_smt_rec(list(initial_terms))

Categories

Resources