|
|
@ -0,0 +1,57 @@ |
|
|
|
solver = z3.Solver() |
|
|
|
|
|
|
|
num = len(matching) |
|
|
|
goal_steps = [[z3.Int(f'g-{n}-{t}') for t in range(num+1)] for n in range(num)] # goal number-of-match time |
|
|
|
goal_steps_bool = [[z3.Bool(f'gb-{n}-{t}') for t in range(num+1)] for n in range(num)] |
|
|
|
start_steps = [[z3.Int(f's-{n}-{t}') for t in range(num+1)] for n in range(num)] # start number-of-match time |
|
|
|
start_steps_bool = [[z3.Bool(f'sb-{n}-{t}') for t in range(num+1)] for n in range(num)] |
|
|
|
|
|
|
|
for n in range(num): |
|
|
|
for t in range(num+1): |
|
|
|
solver.add(z3.Or(start_steps[n][t]==0,start_steps[n][t]==1)) |
|
|
|
solver.add(z3.Or(goal_steps[n][t]==0,goal_steps[n][t]==1)) |
|
|
|
|
|
|
|
# start and end always different |
|
|
|
solver.add(start_steps[n][t] != goal_steps[n][t]) |
|
|
|
|
|
|
|
solver.add(goal_steps_bool[n][t] == z3.If(goal_steps[n][t]==1,True,False)) |
|
|
|
solver.add(goal_steps[n][t] == z3.If(goal_steps_bool[n][t]==True,1,0)) |
|
|
|
solver.add(start_steps_bool[n][t] == z3.If(start_steps[n][t]==1,True,False)) |
|
|
|
solver.add(start_steps[n][t] == z3.If(start_steps_bool[n][t]==True,1,0)) |
|
|
|
|
|
|
|
for t in range(num+1): |
|
|
|
solver.add(z3.Sum([goal_steps[ni][t] for ni in range(num)]) == t) # at t=0, all goals false -> increasing |
|
|
|
|
|
|
|
# given implicitly, s != g |
|
|
|
# starts_at_t = [start_steps[ni][t] for ni in range(num)] |
|
|
|
# solver.add(z3.Sum(starts_at_t) == (num-t)) # at t=0, all start |
|
|
|
|
|
|
|
for n in range(num): |
|
|
|
for t in range(num+1): |
|
|
|
solver.add(z3.Implies(goal_steps_bool[n][t],z3.And(goal_steps_bool[n][t+1:num+1]))) |
|
|
|
|
|
|
|
for s_pt,_,g_vec in start_intersect_triple: |
|
|
|
s_pt_i = find_index_init(matching,s_pt) |
|
|
|
g_vec_i = find_index_goal(matching,g_vec) |
|
|
|
conflicting_starts = [] |
|
|
|
for t in range(num+1): |
|
|
|
conflicting_starts.append(z3.Implies( goal_steps_bool[g_vec_i][t],z3.Or( [z3.Not(start_steps_bool[s_pt_i][ti]) for ti in range(t)] ) )) |
|
|
|
solver.assert_and_track(z3.And(conflicting_starts), f"s-i1:{s_pt_i};i2:{g_vec_i}") |
|
|
|
|
|
|
|
for g_pt,_,g_vec in goal_intersect_triple: |
|
|
|
g_pt_i = find_index_goal(matching,g_pt) |
|
|
|
g_vec_i = find_index_goal(matching,g_vec) |
|
|
|
conflicting_goals = [] |
|
|
|
for t in range(num+1): |
|
|
|
conflicting_goals.append(z3.Implies( goal_steps_bool[g_pt_i][t], z3.Or([goal_steps_bool[g_vec_i][ti] for ti in range(t)]) )) |
|
|
|
solver.assert_and_track(z3.And(conflicting_goals),f"g-i1:{g_pt_i};i2:{g_vec_i}") |
|
|
|
|
|
|
|
|
|
|
|
res = solver.check() |
|
|
|
if res == z3.sat: |
|
|
|
print(solver.model()) |
|
|
|
else: |
|
|
|
core = solver.unsat_core() |
|
|
|
print(solver.sexpr()) |
|
|
|
print(core) |
|
|
|
|