new: PPP.is_partition
make explicit that check_convex option is used in part2convex

Used __add__ is correct, because __add__ calls union with check_convex=True.
But it is somewhat hidden and needs emphasis, because part2convex exists for that reason.

Introduced in: 9fcc3b98f7c7d19d40deb4849bbdf38bb67c6262

Relevant to: 6409fd937aa0a1f5e6a9ea5af77045213b2a800e
but, unlike it, not a bug
distribute polytope.intersect to Polytope.intersect and Region.intersect

to make the code clear and object-oriented and reduce the likelihood of bugs there.
Polytope.intersect now accepts only Polytope arguments.
Region.intersect accepts any iterable container of Polytopes.
new: cheby property of Polytope, Region
bugfix: correct use_all_horizon

which was using the running union of presets to feed it as the new preset for the next step in the iteration over time (up to the 0, starting from the horizon).
This yields erroneous results if drift, control constraints (Uset) or dynamics (A) imply that control cannot keep the system stationary.

The correct version keeps a running union of presets, but feeds back to the iteration the preset resulting from the previous iteration.
debug logging to trace polytope difference bug

polytope.mldivide yields incorrect results if Region comprises of non-adjacent Polytopes.
A sliverish separation of the ingredient Polytopes is sufficient.

Recommendation: In the future Region should check adjacency of its Polytopes upon __init__ and raise an Exception otherwise.
Currently Region is used as a container type with name meaning: disjoint union of Polytopes (never checked). However not all operations on Regions support disconnectedness.

region_diff brakes down when the second Region is disconnected.
This occurs when use_all_horizon (as implemented in 5b1e9681918739b276a221fcc1fd6eebfd058ce3) because the running union can result in a disconnected Region. As noted above, slight separation is sufficient to cause problems.
some more checks in region_diff
bugfix: correct mldivide to handle disconnected Regions

by iteratively subtracting each Polytope of the subtrahend Region from the minuend Region and keeping a running union (assuming disjoint Polytopes comprising the minuend Region), as was already kept.

This appears to fix the problem, i.e., provided that region_diff operate correctly for Polytope \ Polytope set differences, which appears to be the case.

This bug existed and was exposed by: 5b1e9681918739b276a221fcc1fd6eebfd058ce3
It was demonstrated by: 34ad78a5726b40d06ce37fdf61bbb64fa5f9952f
(which btw needs a unit test in the future).
bugfix: separate si \cap s0 during discretization

to avoid adding disconnected Regions to the partition.
Introduced indirectly in:
  5b1e9681918739b276a221fcc1fd6eebfd058ce3
and:
  e2d631634cc7eac838fc06f0f219d9444d17e847
because taking the union of multi-step presets can result in a disconnected Region s0, so the intersection with the desired initial set si will be disconnected (that intersection is isect).
add unit test to guard againt self-loops that don't exist

due to drift, control constraints (Uset) and dynamics
update to Polytope.intersect accepting only Polytopes
don't import box2poly separately from polytope
rewrite PPP.is_partition to exploit symmetry and produce output,

by printing the offending polytopes, the mean volume ratio of their intersection and difference, and save them in numbered plots, to aid debugging.
rename PPP.is_partition -> PPP.are_disjoint

because it doesn't check the other defining properties of a partition
rename PPP.is_preserving -> PPP.is_predicate_preserving

because this is a constraint wrt a set of predicates, not necessarily involving symbols (APs).
mv code from PPP.__init__ to PPP.is_symbolic

to make it available as a method
new: PPP.covers_domain, .is_partition
add to running union during reachability only if it intersects si
return axes handle when unable to plot empty Polytope
raise exception if initial states in synth are empty

because it doesn't help at all to call the solver and let the user miss the warning, thinking that some other problem existed.