How to define set in coq without defining set as a list of elements - set

I am trying to define (1,2,3) as a set of elements in coq. I can define it using list as (1 :: (2 :: (3 :: nil))). Is there any way to define set in coq without using list.

The are basically four possible choices to be made when defining sets in Coq depending on your constraints on the base type of the set and computation needs:
If the base type doesn't have decidable equality, it is common to use:
Definition Set A := A -> Prop
Definition cup A B := fun x => A x /\ B x.
...
basically, Coq's Ensembles. This representation cannot "compute", as we can't even decide if two elements are equal.
If the base data type has decidable equality, then there are two choices depending if extensionality is wanted:
Extensionality means that two sets are equal in Coq's logic iff they have the same elements, formally:
forall (A B : set T), (A = B) <-> (forall x, x \in A <-> x \in B).
If extensionality is wanted, sets should be represented by a canonically-sorted duplicate-free structure, usually a list. A good example is Cyril's Cohen finmap library. This representation however is very inefficient for computing as re-sorting is needed every time a set is modified.
If extensionality is not needed (usually a bad idea if proofs are wanted), you can use representations based on binary trees such as Coq's MSet, which are similar to standard Functional Programming set implementations and can work efficiently.
Finally, when the base type is finite, the set of all sets is a finite type too. The best example of this approach is IMO math-comp's finset, which encodes finite sets as the space of finitely supported membership functions, which is extensional, and forms a complete lattice.

The standard library of coq provides the following finite set modules:
Coq.MSets abstracts away the implementation details of the set. For instance, there is an implementation that uses AVL trees and another based on lists.
Coq.FSets abstracts away the implementation details of the set; it is a previous version of MSets.
Coq.Lists.ListSet is an encoding of lists as sets, which I am including for the sake of completeness
Here is an example on how to define a set with FSets:
Require Import Coq.Structures.OrderedTypeEx.
Require Import Coq.FSets.FSetAVL.
Module NSet := FSetAVL.Make Nat_as_OT.
(* Creates a set with only element 3 inside: *)
Check (NSet.add 3 NSet.empty).

There are many encodings of sets in Coq (lists, function, trees, ...) which can be finite or not. You should have a look at Coq's standard library. For example the 'simplest' set definition I know is this one

Related

Understanding universal restriction of a concept in Description Logic (DL)

I am trying to understand the following Passage from a DL tutorial in terms of First Order Logic (FOL).
Passage
To represent the set of individuals all of whose children are female, we use the universal restriction
∀parentOf.Female (16)
It is a common error to forget that (16) also includes those individuals that have no children at all.
I take (16) to mean "if an individual has children, then those children are all female". My FOL representation of (16) is:
∀x∀y(parentOf(x,y) → Female(y)) (1)
My rational for this translation is that the implicit variable x represents the set of individuals being defined by the role parentOf. I assume x is universally quantified. The variable y represents female children, which I believe is called the successor of x in DL terminology, it is explicitly universally quantified in DL.
My FOL representation of "individuals that have no children at all" in FOL is:
∀x∀y ¬(parentOf(x,y)) (2)
My interpretation of the Passage, in FOL terms, is that if (2) holds then (1) holds. This is because the antecedent of (1) is false in this case.
Is my interpretation of the Passage correct?
Are my translations correct?
About your formula (1)
If you say
∀x∀y(parentOf(x,y) → Female(y))
or, equivalently
∀y((∃x parentOf(x,y)) → Female(y))
you mean that every x can only have female children. But for stating this in DL you need concept inclusion, that is:
⊤ ⊑ ∀parentOf.Female
that means "the range of role parentOf is included in concept Female".
Concept and role inclusions are intensional assertions, i.e., axioms specifying general properties of DL constructs.
Instead, DL's restrictions are not assertions, but constructs like concepts. So they are not used to state properties that are valid for every individual of the ontology. Like, when you say C⊓D, you are not stating that all the individuals of your ontology are instances of C and D, but you are simply "collecting" only the individuals that are instances of C and D at the same time.
Therefore, the formula ∀parentOf.Female just wants to "catch" all the x such that, if x is parent of y, then y is Female. More formally, its semantics is the following:
{x|∀y (parentOf(x,y) → Female(y))}
About your formula (2)
Analogously, the semantics of "individuals that have no children at all" is a set of individuals too:
{x|∀y ¬parentOf(x,y)}
or equivalently
{x|¬∃y parentOf(x,y)}
Indeed, you are collecting all the individuals that have no children, and not stating that all the individuals have no children.
Conclusion
You say right: "if (2) holds then (1) holds". The point is that neither (2) nor (1) (necessarily) hold.
Since you are working with sets, you should not reason in terms of logical inference but of set inclusion.
Therefore, the correct interpretation of the Passage is not
if ∀x∀y ¬(parentOf(x,y)) then ∀x∀y(parentOf(x,y) → Female(y))
but
{x|∀y ¬parentOf(x,y)} is a subset of {x|∀y (parentOf(x,y) → Female(y))}

Testing if one list is a sublist of another without testing equality between elements

I am wondering if one can write a functional program (as in Haskell or OCaml) that takes two lists and determines if the first is a sublist of the second, with the property that the program cannot invoke equality between elements of the list.
More generally, is there such a program that works for lists of elements of arbitrary type? That is, (in Haskell terms) the type does not have to be constrained by Eq, Ord, or something else.
The reason I ask this is that when dealing with lists of elements of arbitrary type, standard equality (as for ints, strings, etc.) is sometimes not supported for these elements. It would be helpful, however, to test for sublists.
I have been unable to think of an implementation that meets this condition. Is it possible to create one?
Without an equality, the relation is_sublist is non-sensical: [x] `is_sublist` [y] ought to be true if and only if x = y. Conversely, if such function is_sublist existed, it would define an equality function as eq x y = [x] `is_sublist` [y] .

Example channelling constraints ECLiPSe

Can someone provide a simple example of channelling constraints?
Channelling constraints are used to combine viewpoints of a constraint problem. Handbook of Constraint Programming gives a good explanation of how it works and why it can be useful:
The search variables can be the variables of one of the viewpoints, say X1 (this is discussed further below). As
search proceeds, propagating the constraints C1 removes values from the domains of the
variables in X1. The channelling constraints may then allow values to be removed from
the domains of the variables in X2. Propagating these value deletions using the constraints
of the second model, C2, may remove further values from these variables, and again these
removals can be translated back into the first viewpoint by the channelling constraints. The
net result can be that more values are removed within viewpoint V1 than by the constraints
C1 alone, leading to reduced search.
I do not understand how this is implemented. What are these constraints exactly, how do they look like in a real problem? A simple example would be very helpful.
As stated in Dual Viewpoint Heuristics for Binary Constraint Satisfaction Problems (P.A. Geelen):
Channelling constraints of two different models allows for the expression of a relationship between two sets of variables, one of each model.
This implies assignments in one of the viewpoints can be translated into assignments in the other and vice versa, as well as, when search initiates,
excluded values from one model can be excluded from the other as well.
Let me throw in an example I implemented a while ago while writing a Sudoku solver.
Classic viewpoint
Here we interpret the problem in the same way a human would: using the
integers between 1 and 9 and a definition that all rows, columns and blocks must contain every integer exactly once.
We can easily state this in ECLiPSe using something like:
% Domain
dim(Sudoku,[N,N]),
Sudoku[1..N,1..N] :: 1..N
% For X = rows, cols, blocks
alldifferent(X)
And this is yet sufficient to solve the Sudoku puzzle.
Binary boolean viewpoint
One could however choose to represent integers by their binary boolean arrays (shown in the answer by #jschimpf). In case it's not clear what this does, consider the small example below (this is built-in functionality!):
?­ ic_global:bool_channeling(Digit, [0,0,0,1,0], 1).
Digit = 4
Yes (0.00s cpu)
?­ ic_global:bool_channeling(Digit, [A,B,C,D], 1), C = 1.
Digit = 3
A = 0
B = 0
C = 1
D = 0
Yes (0.00s cpu)
If we use this model to represent a Sudoku, every number will be replaced by its binary boolean array and corresponding constraints can be written. Being trivial for this answer, I will not include all the code for the constraints, but a single sum constraint is yet enough to solve a Sudoku puzzle in its binary boolean representation.
Channelling
Having these two viewpoints with corresponding constrained models now gives the opportunity to channel between them and see if any improvements were made.
Since both models are still just an NxN board, no difference in dimension of representation exists and channelling becomes real easy.
Let me first give you a last example of what a block filled with integers 1..9 would look like in both of our models:
% Classic viewpoint
1 2 3
4 5 6
7 8 9
% Binary Boolean Viewpoint
[](1,0,0,0,0,0,0,0,0) [](0,1,0,0,0,0,0,0,0) [](0,0,1,0,0,0,0,0,0)
[](0,0,0,1,0,0,0,0,0) [](0,0,0,0,1,0,0,0,0) [](0,0,0,0,0,1,0,0,0)
[](0,0,0,0,0,0,1,0,0) [](0,0,0,0,0,0,0,1,0) [](0,0,0,0,0,0,0,0,1)
We now clearly see the link between the models and simply write the code to channel our decision variables. Using Sudoku and BinBools as our boards, the code would look something like:
( multifor([Row,Col],1,N), param(Sudoku,BinBools,N)
do
Value is Sudoku[Row,Col],
ValueBools is BinBools[Row,Col,1..N],
ic_global:bool_channeling(Value,ValueBools,1)
).
At this point, we have a channelled model where, during search, if values are pruned in one of the models, its impact will also occur in the other model. This can then of course lead to further overall constraint propagation.
Reasoning
To explain the usefulness of the binary boolean model for the Sudoku puzzle, we must first differentiate between some provided alldifferent/1 implementations by ECLiPSe:
What this means in practice can be shown as following:
?­ [A, B, C] :: [0..1], ic:alldifferent([A, B, C]).
A = A{[0, 1]}
B = B{[0, 1]}
C = C{[0, 1]}
There are 3 delayed goals.
Yes (0.00s cpu)
?­ [A, B, C] :: [0..1], ic_global:alldifferent([A, B, C]).
No (0.00s cpu)
As there has not yet occurred any assignment using the Forward Checking (ic library), the invalidity of the query is not yet detected, whereas the Bounds Consistent version immediately notices this. This behaviour can lead to considerable differences in constraint propagation while searching and backtracking through highly constrained models.
On top of these two libraries there is the ic_global_gac library intended for global constraints for which generalized arc consistency (also called hyper arc consistency or domain consistency) is maintained. This alldifferent/1 constraint provides even more pruning opportunities than the bounds consistent one, but preserving full domain consistency has its cost and using this library in highly constrained models generally leads to a loss in running performance.
Because of this, I found it interesting for the Sudoku puzzle to try and work with the bounds consistent (ic_global) implementation of alldifferent to maximise performance and subsequently try to approach domain consistency myself by channelling the binary boolean model.
Experiment results
Below are the backtrack results for the 'platinumblonde' Sudoku puzzle (referenced as being the hardest, most chaotic Sudoku puzzle to solve in The Chaos Within Sudoku, M. Ercsey­Ravasz and Z. Toroczkai) using respectively forward checking, bounds consistency, domain consistency, standalone binary boolean model and finally, the channelled model:
(ic) (ic_global) (ic_global_gac) (bin_bools) (channelled)
BT 6 582 43 29 143 30
As we can see, our channelled model (using bounds consistency (ic_global)) still needs one backtrack more than the domain consistent implementation, but it definitely performs better than the standalone bounds consistent version.
When we now take a look at the running times (results are the product of calculating an average over multiple executions, this to avoid extremes) excluding the forward checking implementation as it's proven to no longer be interesting for solving Sudoku puzzles:
(ic_global) (ic_global_gac) (bin_bools) (channelled)
Time(ms) 180ms 510ms 100ms 220ms
Looking at these results, I think we can successfully conclude the experiment (these results were confirmed by 20+ other Sudoku puzzle instances):
Channelling the binary boolean viewpoint to the bounds consistent standalone implementation produces a slightly less strong constraint propagation behaviour than that of the domain consistent standalone implementation, but with running times ranging from just as long to notably faster.
EDIT: attempt to clarify
Imagine some domain variable representing a cell on a Sudoku board has a remaining domain of 4..9. Using bounds consistency, it is guaranteed that for both value 4 and 9 other domain values can be found which satisfy all constraints and thus provides consistency. However, no consistency is explicitly guaranteed for other values in the domain (this is what 'domain consistency' is).
Using a binary boolean model, we define the following two sum constraints:
The sum of every binary boolean array is always equal to 1
The sum of every N'th element of every array in every row/col/block is always equal to 1
The extra constraint strength is enforced by the second constraint which, apart from constraining row, columns and blocks, also implicitly says: "every cell can only contain every digit once". This behaviour is not actively expressed when using just the bounds consistent alldifferent/1 constraint!
Conclusion
It is clear that channelling can be very useful to improve a standalone constrained model, however if the new model's constraint strengthness is weaker than that of the current model, obviously, no improvements will be made. Also note that having a more constrained model doesn't necesarilly also mean an overall better performance! Adding more constraints will in fact decrease amounts of backtracks required to solve a problem, but it might also increase the running times of your program if more constraint checks have to occur.
Channeling constraints are used when, in a model, aspects of a problem are represented in more than one way. They are then necessary to synchronize these multiple representations, even though they do not themselves model an aspect of the problem.
Typically, when modelling a problem with constraints, you have several ways of choosing your variables. For example, in a scheduling problem, you could choose to have
an integer variable for each job (indicating which machine does the job)
an integer variable for each machine (indicating which job it performs)
a matrix of Booleans (indicating which job runs on which machine)
or something more exotic
In a simple enough problem, you choose the representation that makes it easiest to formulate the constraints of the problem. However, in real life problems with many heterogeneous constraints it is often impossible to find such a single best representation: some constraints are best represented with one type of variable, others with another.
In such cases, you can use multiple sets of variables, and formulate each individual problem constraint over the most convenient variable set. Of course, you then end up with multiple independent subproblems, and solving these in isolation will not give you a solution for the whole problem. But by adding channeling constraints, the variable sets can be synchronized, and the subproblems thus re-connected. The result is then a valid model for the whole problem.
As hinted in the quote from the handbook, in such a formulation is is sufficient to perform search on only one of the variable sets ("viewpoints"), because the values of the others are implied by the channeling constraints.
Some common examples for channeling between two representations are:
Integer variable and Array of Booleans:
Consider an integer variable T indicating the time slot 1..N when an event takes place, and an array of Booleans Bs[N] such that Bs[T] = 1 iff an event takes place in time slot T. In ECLiPSe:
T #:: 1..N,
dim(Bs, [N]), Bs #:: 0..1,
Channeling between the two representations can then be set up with
( for(I,1,N), param(T,Bs) do Bs[I] #= (T#=I) )
which will propagate information both ways between T and Bs. Another way of implementing this channeling is the special purpose bool_channeling/3 constraint.
Start/End integer variables and Array of Booleans (timetable):
We have integer variables S,E indicating the start and end time of an activity. On the other side an array of Booleans Bs[N] such that Bs[T] = 1 iff the activity takes place at time T. In ECLiPSe:
[S,E] #:: 1..N,
dim(Bs, [N]), Bs #:: 0..1,
Channeling can be achieved via
( for(I,1,N), param(S,E,Bs) do Bs[I] #= (S#=<I and I#=<E) ).
Dual representation Job/Machine integer variables:
Here, Js[J] = M means that job J is executed on machine M, while the dual formulation Ms[M] = J means that machine M executes job J
dim(Js, [NJobs]), Js #:: 0..NMach,
dim(Ms, [NMach]), Ms #:: 1..NJobs,
And channeling is achieved via
( multifor([J,M],1,[NJobs,NMach]), param(Js,Ms) do
(Js[J] #= M) #= (Ms[M] #= J)
).
Set variable and Array of Booleans:
If you use a solver (such as library(ic_sets)) that can directly handle set-variables, these can be reflected into an array of booleans indicating membership of elements in the set. The library provides a dedicated constraint membership_booleans/2 for this purpose.
Here is a simple example, works in SWI-Prolog, but should
also work in ECLiPSe Prolog (in the later you have to use (::)/2 instead of (in)/2):
Constraint C1:
?- Y in 0..100.
Y in 0..100.
Constraint C2:
?- X in 0..100.
X in 0..100.
Channelling Constraint:
?- 2*X #= 3*Y+5.
2*X#=3*Y+5.
All together:
?- Y in 0..100, X in 0..100, 2*X #= 3*Y+5.
Y in 1..65,
2*X#=3*Y+5,
X in 4..100.
So the channel constraint works in both directions, it
reduces the domain of C1 as well as the domain of C2.
Some systems use iterative methods, with the result that this channelling
can take quite some time, here is an example which needs around
1 minute to compute in SWI-Prolog:
?- time(([U,V] ins 0..1_000_000_000, 36_641*U-24 #= 394_479_375*V)).
% 9,883,559 inferences, 53.616 CPU in 53.721 seconds
(100% CPU, 184341 Lips)
U in 346688814..741168189,
36641*U#=394479375*V+24,
V in 32202..68843.
On the other hand ECLiPSe Prolog does it in a blink:
[eclipse]: U::0..1000000000, V::0..1000000000,
36641*U-24 #= 394479375*V.
U = U{346688814 .. 741168189}
V = V{32202 .. 68843}
Delayed goals:
-394479375 * V{32202 .. 68843} +
36641 * U{346688814 .. 741168189} #= 24
Yes (0.11s cpu)
Bye

Challenge on Alphabet and Formal Grammar and Language

We know set A is countable if A is finite or in a one-to-one mapping to natural numbers.
Suppose ALPH be an arbitrary finite alphabet.
I summarize my inference:
a) Each arbitrary Language on ALPH is Countable. (I think this is True)
b) the set of all language from ALPH is Countable.(I think this is False)
c) for Each arbitrary Language on ALPH we have a generative formal grammar. (I think this is False)
d) Each arbitrary Language on ALPH that can be generated by formal grammar, is recursive. (I think this is True)
anyone could help me, and maybe correct me?
Without loss of generality, we can assume that ALPH is merely the set {0,1}. (Any other finite language can of course be encoded using the set {0,1}). Assuming that by a language L that you intend some arbitrary subset of ALPH*, we can assume that L is an arbitrary subset of {0,1}*.
Let S = {0,1}*.
a) The set S is countable. Since L is a subset of S, L is countable.
b) The set of all languages over S then is the powerset of S, which can be put into 1-1 correspondence with the Real numbers. Hence, not countable.
c) I believe that this is false, agreeing with your supposition. However, it depends on your definition of a 'generative formal grammar'. If you allow for formal grammars where individual rules of the grammar are undecidable, and/or allow for infinite generation rules, this becomes less clear. For any particular definition for 'generative formal grammar', where the collection of 'generative formal grammars' is enumerable, then of course, the answer is false.
d) In general, I believe that the answer to this is false. If you restrict yourself to formal grammars corresponding to context-free languages, then of course, your answer is true. However, consider http://en.wikipedia.org/wiki/Post_correspondence_problem The problem is undecidable, yet the generation rules are pretty clear.

Purely functional set

Is there an algorithm that implements a purely functional set?
Expected operations would be union, intersection, difference, element?, empty? and adjoin.
Those are not hard requirements though and I would be happy to learn an algorithm that only implements a subset of them.
You can use a purely functional map implementation, where you just ignore the values.
See http://hackage.haskell.org/packages/archive/containers/0.1.0.1/doc/html/Data-IntMap.html (linked to from https://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki ).
(sidenote: For more information on functional datastructures, see http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504 )
A purely functional implementation exists for almost any data structure. In the case of sets or maps, you typically use some form of search tree, e.g. red/black trees or AVL trees. The standard reference for functional data structures is the book by Okasaki:
http://www.cambridge.org/gb/knowledge/isbn/item1161740/
Significant parts of it are available for free via his thesis:
http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
The links from the answer by #ninjagecko are good. What I've been following recently are the Persistent Data Structures used in Clojure, which are functional, immutable and persistent.
A description of the implementation of the persistent hash map can be found in this two-part blog post:
http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/
http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii/
These are implementations of some of the ideas (see the first answer, first entry) found in this reference request question.
The sets that come out of these structures support the functions you need:
http://clojure.org/data_structures#Data Structures-Sets
All that's left is to browse the source code and try to wrap your head around it.
Here is an implementation of a purely functional set in OCaml (it is the standard library of OCaml).
Is there an algorithm that implements a purely functional set?
You can implement set operations using many different purely functional data structures. Some have better complexity than others.
Examples include:
Lists
Where we have:
List Difference:
(\\) :: Eq a => [a] -> [a] -> [a]
The \\ function is list difference ((non-associative). In the result of xs \\ ys, the first occurrence of each element of ys in turn (if any) has been removed from xs. Thus
union :: Eq a => [a] -> [a] -> [a]
The union function returns the list union of the two lists. For example,
"dog" `union` "cow" == "dogcw"
Duplicates, and elements of the first list, are removed from the the second list, but if the first list contains duplicates, so will the result. It is a special case of unionBy, which allows the programmer to supply their own equality test.
intersect :: Eq a => [a] -> [a] -> [a]
The intersect function takes the list intersection of two lists. For example,
[1,2,3,4] `intersect` [2,4,6,8] == [2,4]
If the first list contains duplicates, so will the result.
Immutable Sets
More efficient data structures can be designed to improve the complexity of set operations. For example, the standard Data.Set library in Haskell implements sets as size-balanced binary trees:
Stephen Adams, "Efficient sets: a balancing act", Journal of Functional Programming 3(4):553-562, October 1993, http://www.swiss.ai.mit.edu/~adams/BB/.
Which is this data structure:
data Set a = Bin !Size !a !(Set a) !(Set a)
| Tip
type Size = Int
Yielding complexity of:
union, intersection, difference: O(n+m)

Resources