I am lost in the sea of different kinds of constraint solvers available. I am writing a database query program.
Given an equation where terms are sets of non-consecutive integers, my goal is to simplify the equation as the influence of some terms might completely overlap or be completely disjoint in/from the resulting set, therefore making them discardable.
Example:
({1, 2} ∪ {3, 4}) - {4, 6}
as a first step can be simplified to:
({1, 2} ∪ {3, 4}) - {4}
since {6} ⊄ ({1, 2} ∪ {3, 4}), etc.
What kind of solver can one use for such a problem? I found library(fd_sets) which seems appropriate. However, ECLiPSE is not an easy platform to work with. Are there other solutions?
({1, 2} ∪ {3, 4}) - {4, 6}
is not an equation (or constraint), so there is nothing to solve. So you don't need a solver. It is a (constant) expression. We can easily evaluate this expression and print the result. E.g. in straightforward Python:
print({1,2}.union({3,4}).difference({4,6}))
will give
{1, 2, 3}
Python knows about sets, so that makes it easy. To automatically go from ({1, 2} ∪ {3, 4}) - {4, 6} to {1,2}.union({3,4}).difference({4,6}), you would need to build a parser. This is not very difficult to do (for a skilled programmer). If your favorite programming language does not know about sets, it is not too difficult to create data structures and functions to handle sets. Many languages have some support for sets (e.g. the standard C++ library has sets).
PS. To be complete: Python also allows infix set operators. E.g.:
print({1,2} | {3,4} - {4,6})
Related
I am trying to write a technical report that explains my algorithm for my work and instead of writing long pseudocode, I want to write it in neat mathematical notations. However, because of my limited knowledge of math, I cannot come up with a clean and straightforward notation for the below pseudocode:
elements = [a, b, ..., z] // a sequence of some elements with size K.
interested_poses = {1, 4, ... t} // a set of indexes of elements that we are interested in.
results = ∅ // an empty set to hold result elements.
FOR I = 1 to K DO
IF I ∈ interested_poses THEN
ADD elements[I] to results
If someone can guide me how I can convert the above to math notations, that would be very much appreciated as well as some references that I can use for further study for myself.
Thanks in advance.
For a proof I'm working on in Isabelle I need the facts that 3 and 5 are primes. What would be the simplest way to establish this?
There are simp rules that allow the simplifier to do that automatically:
lemma "prime (5 :: nat)"
by simp
For larger numbers (e.g. 137), this will take a few seconds, and for much larger numbers, it is completely unusable.
You can also use eval instead of simp, which goes through Isabelle's evaluation oracle to evaluate the statement inside Standard ML and then reinterprets the result as a theorem in Isabelle. Depending on whom you ask, this may be seen as slightly less trustworthy than simp.
Lastly, there the entry on Pratt Certificates in the Archive of Formal Proofs also provides a proof method called pratt, which can automatically prove the primality of a number using Pratt certificates. This is slightly more efficient than using simp, but still not great for really big numbers.
In any case, for small numbers like 5 and 7, by simp is the way to go.
Note however that you must give a type, i.e. prime (5 :: nat) or prime (7 :: int). If you just write prime 5, the type that is inferred for 5 is too general. For instance, prime (5 :: real) is not true, since fields contain no prime numbers.
How can I prove in Isabelle the simple lemma cd : "card {m∈ℕ. m <4} = 4" statement?
auto doesn't help me and oddly sledgehammer times out (even if I use different values on the right-hand side, like 3 or 5 to make sure that I haven't overlooked some technical Isabelle details which perhaps actually make the cardinaliy evaluate to one of these numbers.)
I have the impression that I have to use some lemmas (or get inspiration) from Set_Interval.thy as there sets of these kind are extensively used, but so far I didn't manage to make progress.
Just wanted to add, that if you rewrite your lemma to "card {m::nat. m < n} = n", Isabelle has no problem proving it.
*Edited, thanks Manuel.
The problem with your statement is that it is not true. Look at the definition of ℕ with thm Nats_def: ℕ = range of_nat
of_nat is the canonical homomorphism from the naturals into a semiring_1, i.e. a semiring that has a 1. The definition of ℕ basically says that ℕ consists of all the elements of the ring that are of the form of_nat n for a natural number n. If you look at the type of {m∈ℕ. m <4}, you will see that it is 'a, or if you do a declare [[show_sorts]] before it, 'a :: {ord, semiring_1}, i.e. a semiring with a 1 and some kind of ordering on it. This ordering does not have to be compatible with the ring structure, nor does it have to be linear.
You may think that the set you defined is always the set {0, 1, 2, 3}, but because the ordering is not required to be compatible with the ring structure, this is not the case. The ordering could be trivially true, so you'll get all natural numbers.
Furthermore, even when the set is {0, 1, 2, 3}, its cardinality is not necessarily 4. (Think of the ring ℤ/2ℤ – then that set will be equal to {0, 1}, so the cardinality is 2)
You will probably want to restrict the type of your expression a bit. I think the right type class here is linordered_semidom, i.e. a semiring with a 1, no zero divisors, and a linear ordering that is compatible to the ring structure. Then you can do:
lemma cd : "card {m∈ℕ. m < (4 :: 'a :: linordered_semidom)} = 4"
proof -
have "{m∈ℕ. m < (4 :: 'a)} = {m∈ℕ. m < (of_nat 4 :: 'a)}" by simp
also have "… = of_nat ` {m. m < 4}"
unfolding Nats_def by (auto simp del: of_nat_numeral)
also have "card … = 4" by (auto simp: inj_on_def card_image)
finally show ?thesis .
qed
The proof is a bit ugly considering how intuitively obvious the proposition is; the solution here is not to write down the set you want to describe in this relatively inconvenient way in the first place. It takes a bit of experience to know how to write things in a convenient way.
I would write {1, 2} + {3} + {4} = {1, 2, 3, 4} in maths to say that the sets on LHS partition that of RHS. Is there something similar in isabelle so I don't need to go through all the permutations {1, 2} intersect {3} = {} etc.
[EDIT]
I've found this disjoint definition in the probability sigma algebra package but is there anything that wouldn't introduce that dependency?
disjoint is probably the best choice. You can just copy the definition and the few lemmas after it to your own theory.
I will talk to Johannes Hölzl (who made the Probability Theory library) and ask him what he thinks about moving disjoint into HOL so that it is available with no extra imports.
In the development version of Isabelle (http://isabelle.in.tum.de/repos/isabelle/rev/53697011b03a) it is now in its own theory file:
~~/src/HOL/Library/Disjoint_Sets
In my Isabelle formalisation I'm dealing with finite sets of natural numbers, and on these sets I'd like to consider functions that have the property of being a linear order.
I see that there are several different formalisations of orders in the library, but I'm not sure which one to reuse. In most cases those functions of which I'd like to check whether they are linear orders will simply be defined by using library operators such as < (less), but in some cases they might be defined as more complex combinations of library functions.
I tried HOL/Library/Order_Relation, but that doesn't seem to be connected to <; e.g. I'm unable to have the following lemma proved automatically:
lemma "linear_order_on {1::nat, 2} {(a::nat, b) . {a, b} ⊆ {1::nat, 2} ∧ a < b}"
(I'm sure there are nicer ways of converting a function to a relation, but that's not the main point here.)
If there were some ready-to-reuse library could I'd appreciate if you could let me know. Modelling this in a mathematically elegant way is not of utmost importance to me right now, so for now I'm considering to resort to functions that assign rational or real numbers to the natural numbers in my sets, and then using < on these rational/real numbers.
I don't really know if there are better theories to use, but the lemma you have given is (still after the fix) false (the given relation is irreflexive while the expected one should be reflexive). Here are two versions that are correct:
lemma "linear_order_on {1::nat, 2} {(a::nat, b) . {a, b} ⊆ {1::nat, 2} ∧ a ≤ b}"
unfolding linear_order_on_def partial_order_on_def preorder_on_def
refl_on_def total_on_def trans_def antisym_def
by auto
lemma "strict_linear_order_on {1::nat, 2} {(a::nat, b) . {a, b} ⊆ {1::nat, 2} ∧ a < b}"
unfolding strict_linear_order_on_def partial_order_on_def preorder_on_def
irrefl_def total_on_def trans_def antisym_def
by auto