You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
2.3 KiB

  1. solver = z3.Solver()
  2. num = len(matching)
  3. goal_steps = [[z3.Int(f'g-{n}-{t}') for t in range(num+1)] for n in range(num)] # goal number-of-match time
  4. goal_steps_bool = [[z3.Bool(f'gb-{n}-{t}') for t in range(num+1)] for n in range(num)]
  5. start_steps = [[z3.Int(f's-{n}-{t}') for t in range(num+1)] for n in range(num)] # start number-of-match time
  6. start_steps_bool = [[z3.Bool(f'sb-{n}-{t}') for t in range(num+1)] for n in range(num)]
  7. for n in range(num):
  8. for t in range(num+1):
  9. solver.add(z3.Or(start_steps[n][t]==0,start_steps[n][t]==1))
  10. solver.add(z3.Or(goal_steps[n][t]==0,goal_steps[n][t]==1))
  11. # start and end always different
  12. solver.add(start_steps[n][t] != goal_steps[n][t])
  13. solver.add(goal_steps_bool[n][t] == z3.If(goal_steps[n][t]==1,True,False))
  14. solver.add(goal_steps[n][t] == z3.If(goal_steps_bool[n][t]==True,1,0))
  15. solver.add(start_steps_bool[n][t] == z3.If(start_steps[n][t]==1,True,False))
  16. solver.add(start_steps[n][t] == z3.If(start_steps_bool[n][t]==True,1,0))
  17. for t in range(num+1):
  18. solver.add(z3.Sum([goal_steps[ni][t] for ni in range(num)]) == t) # at t=0, all goals false -> increasing
  19. # given implicitly, s != g
  20. # starts_at_t = [start_steps[ni][t] for ni in range(num)]
  21. # solver.add(z3.Sum(starts_at_t) == (num-t)) # at t=0, all start
  22. for n in range(num):
  23. for t in range(num+1):
  24. solver.add(z3.Implies(goal_steps_bool[n][t],z3.And(goal_steps_bool[n][t+1:num+1])))
  25. for s_pt,_,g_vec in start_intersect_triple:
  26. s_pt_i = find_index_init(matching,s_pt)
  27. g_vec_i = find_index_goal(matching,g_vec)
  28. conflicting_starts = []
  29. for t in range(num+1):
  30. 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)] ) ))
  31. solver.assert_and_track(z3.And(conflicting_starts), f"s-i1:{s_pt_i};i2:{g_vec_i}")
  32. for g_pt,_,g_vec in goal_intersect_triple:
  33. g_pt_i = find_index_goal(matching,g_pt)
  34. g_vec_i = find_index_goal(matching,g_vec)
  35. conflicting_goals = []
  36. for t in range(num+1):
  37. 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)]) ))
  38. solver.assert_and_track(z3.And(conflicting_goals),f"g-i1:{g_pt_i};i2:{g_vec_i}")
  39. res = solver.check()
  40. if res == z3.sat:
  41. print(solver.model())
  42. else:
  43. core = solver.unsat_core()
  44. print(solver.sexpr())
  45. print(core)