How to create a Powerset of MSetList? - coq

I am creating an MSetList P with elements of type String, and I would like to obtain the Powerset of P. I am not being able to figure it out.
Code below.
Thanks for your help :-)
Require Import
Coq.MSets.MSetList
Coq.Strings.String
Coq.Structures.OrdersEx.
Module set := Make OrdersEx.String_as_OT.
Definition P := set.add "A"%string (set.add "B"%string (set.add "C"%string (set.add "D"%string set.empty))).
Compute P.

Answer was provided on the Coq Discourse Forum by Yves Bertot
The construction of set shows that you are using the Make function
with a module as argument. If you type Print Make., you see that
this is a functor taking a module of type OrderedType as argument,
and it produces a module with many fields, among which t, eq,
eq_equiv, lt, lt_strorder, lt_compat, compare,
compare_spec, and eq_dec. If you type Print OrderedType., you
see that these field are the ones required to make an OrderedType.
So Make constructs all the fields that would be required to call Make
again, thus producing the powerset.
You can just type :
Module pset := Make set.
and you will simply obtain a structure of sets, whose elements are in
set.t. The following example was tested with coq 8.15.
Require Import
Coq.MSets.MSetList
Coq.Strings.String
Coq.Structures.OrdersEx.
Module set := Make OrdersEx.String_as_OT.
Module pset := Make set.
Definition set1 := set.add "A"%string set.empty.
Definition set2 := set.add "B"%string set.empty.
Definition set3 := set.add "C"%string set1.
Definition pset1 := pset.add set1 (pset.add set2 pset.empty).
Compute pset.mem set3 pset1.
Compute pset.mem set2 pset1.

Related

Coercion within data structures

The following code gives me an error:
Require Import Reals.
Require Import List.
Import ListNotations.
Open Scope R_scope.
Definition C := (R * R)%type.
Definition RtoC (r : R) : C := (r,0).
Coercion RtoC : R >-> C.
Definition lC : list C := [0;0;0;1].
Error: The term "[0; 0; 0; 1]" has type "list R" while it is expected to have type "list C".
But I've defined RtoC as a coercion and I don't see any problems when I use
Definition myC : C := 4.
How do I get Coq to apply the coercion within the list?
Related question: If I enter Check [0;0;0;1] it returns list R, inserting an implicit IZR before every number. Why does Coq think I want Rs rather than Zs?
I'm unsure there is a fully satisfying solution to your question.
Indeed, as recalled in the Coq refman:
Given a term, possibly not typable, we are interested in the problem of determining if it can be well typed modulo insertion of appropriate coercions.
and it turns out that in your example, the term [0;0;0;1] itself is typable as a list R and it is type-checked "in one go"; thereby when the [0;0;0;1] : list C type mismatch occurs, as there's no "backtracking", a coercion can't be inserted within the list elements.
So maybe you could adapt your formalization in a different way, or just use one of these workarounds:
Rewriting your term into a β-redex:
Definition lC := (fun z o => [z;z;z;o] : list C) 0 1.
Or inserting a few more typecasts around each element:
Definition lC := [0:C; 0:C; 0:C; 1:C].
Regarding your last question
Why does Coq think I want Rs rather than Zs?
this comes from your line Open Scope R_scope., which implies numeral litterals are recognized by default as belonging to R (which deals with the classical axiomatization of the real numbers formalized in the standard library Reals). More specifically, the implementation has changed in Coq 8.7, as from coq/coq#a4a76c2 (discussed in PR coq/coq#415). To sum up, a literal such as 5%R is now parsed as IZR 5, that is, IZR (Zpos (xI (xO xH))), while it used to be parsed to a much less concise term in Coq 8.6:
Rplus R1 (Rmult (Rplus R1 R1) (Rplus R1 R1)).

Translate the Maude code into Coq

I want to translate the Maude code I wrote before to Coq since Coq has more powerful expression than Maude.
I have no idea how to represent the following code:
As shown above, the GuardPostfix has three subsorts: GuardPostfix1, GuardPostfix2 and GuardPostfix3.
I use inductive type to denote the GCcomponent. However, when defining the type GComponent, GComponent1 has two constructors that use the constructor GuardPostfix1 and GuardPostfix2 respectively.
How can I define these types in Coq?
I think the general recipe is to translate all Maude sorts into Coq types, and to represent Maude subsort relationships as the supersort having constructors for all of its subsorts (eg, subsort A B < C becomes Definition C := A + B). Following that general rule here's how I translated your example. Note that I don't know Maude, so it's possibly I missed something about the example itself. Also, I would strongly consider using a new inductive rather than the generic sum type (+) for GuardPostfix and GComponent, but that's up to you.
Module GuardedComponent.
Parameter BoolExp:Type.
Parameter Assignment:Type.
Parameter Program:Type.
Parameter Index:Type.
Parameter EndPoint:Type.
Parameter Null:Type.
Parameter EventGuard:Type.
Parameter TimeControl:Type.
Inductive AssignmentGuard :=
| mkAssignmentGuard (_:BoolExp) (_:Assignment).
Inductive GuardPostfix1 :=
| mkGuardPostfix1 (_:Program) (_:Index).
Inductive GuardPostfix2 :=
| mkGuardPostfix2 (_:Program) (_:EndPoint).
Inductive GuardPostfix3 :=
| mkGuardPostfix3 (_:Program) (_:Null).
Definition GuardPostfix : Type :=
GuardPostfix1 + GuardPostfix2 + GuardPostfix3.
Inductive GComponent1 :=
| comp1_post1 (_:GuardPostfix1)
| comp1_post2 (_:GuardPostfix2).
Inductive GComponent2 :=
| mkGComponent2 (_:EventGuard) (_:GuardPostfix3).
Inductive GComponent3 :=
| mkGComponent3 (_:TimeControl) (_:GuardPostfix3).
Definition GComponent : Type :=
GComponent1 + GComponent2 + GComponent3.
End GuardedComponent.

How to convert DOM::MATRIX to Function

A simple example of what I am doing is as follows:
s := t*0.2:
b := matrix([0.5,0.6,0.1]):
f := matrix([sin(s),cos(s),s]):
X := transpose(b)*(f);
plotfunc2d(X,t=-2*PI..2*PI);
The error is:
Error: Expecting an arithmetical expression or a function. Got a 'Dom::Matrix()' for attribute 'Function' in the 'Function2d' object.
so, I need to convert types from Dom::Matrix to Function. I have tried:
coerce(X,DOM_EXPR);
I know that simply, this works:
s := t*0.2:
x := 0.5*sin(s)+0.6*cos(s)+0.1*s;
plotfunc2d(x,t=-2*PI..2*PI);
Is there a way to convert these types?
While the variable X itself is a DOM::Matrix(), the single element it contains is an arithmetical expression, so you need to pass the element itself to the plot function:
plotfunc2d(X[1],t=-2*PI..2*PI);

How do you make notations visible outside of a module signature in Coq?

I've defined a module signature in Coq that defines several notations. When I try to use these notations outside of the signature however, Coq fails. A simplified version of my code is given below. Any help would be appreciated.
Module Type Field_Axioms.
Delimit Scope Field_scope with F.
Open Scope Field_scope.
Parameter Element : Set.
Parameter addition : Element -> Element -> Element.
Infix " + " := addition : Field_scope. (* ASSIGNS THE "+" OPERATOR TO SCOPE. *)
End Field_Axioms
Module Type Ordered_Field_Axioms.
Declare Module Field : Field_Axioms.
Print Scope Field_scope. (* SHOWS THAT THE SCOPE IS EMPTY. *)
End Ordered_Field_Axioms.
You can replace:
Declare Module Field : Field_Axioms.
with:
Declare Module Import Field : Field_Axioms.

New Scope in Coq

I'd like my own scope, to play around with long distfixes.
Declare Scope my_scope.
Delimit Scope my_scope with my.
Open Scope my_scope.
Definition f (x y a b : nat) : nat := x+y+a+b.
Notation "x < y * a = b" := (f x y a b)
(at level 100, no associativity) : my_scope.
Check (1 < 2 * 3 = 4)%my.
How do you make a new scope?
EDIT: I chose "x < y * a = b" to override Coq's operators (each with a different precedence).
The command Declare Scope does not exist. The various commands about scopes are described in section 12.2 of the Coq manual.
Your choice of an example notation has inherent problems, because it clashes with pre-defined notations, which seem to be used before your notation.
When looking at the first components the parser sees _ < _ and thinks that you are actually talking about comparison of integers, then it sees the second part as being an instance of the notation _ * _, then it sees that all that is the left hand side of an equality. And all along the parser is happy, it constructs an expression of the form:
(1 < (2 * 3)) = 4
This is constructed by the parser, and the type system has not been solicited yet. The type checker sees a natural number as the first child of (_ < _) and is happy. It sees (_ * _) as the second child and it is happy, it now knows that the first child of that product should be a nat number and it is still happy; in the end it has an equality, and the first component of this equality is in type Prop, but the second component is in type nat.
If you type Locate "_ < _ * _ = _". the answer tells you that you did define a new notation. The problem is that this notation never gets used, because the parser always finds another notation it can use before. Understanding why a notation is preferred to another one requires more knowledge of parsing technology, as alluded to in Coq's manual, chapter 12, in the sentence (obscure to me):
Coq extensible parsing is performed by Camlp5 which is essentially a LL1 parser.
You have to choose the levels of the various variables, x, y, a, and b so that none of these variables will be able to match too much of the text. For instance, I tried defining a notation close to yours, but with a starting and an ending bracket (and I guess this simplifies the task greatly).
Notation "<< x < y * a = b >>" := (f x y a b)
(x at level 59, y at level 39, a at level 59) : my_scope.
The level of x is chosen to be lower than the level of =, the level of y is chosen to be lower than the level of *, the level of a is chosen to be lower than =. The levels were obtained by reading the answer of the command Print Grammar constr. It seems to work, as the following command is accepted.
Check << 1 < 2 * 3 = 4 >>.
But you may need to include a little more engineering to have a really good notation.
To answer the actual question in your title:
The new scope gets created when you declare a notation that uses it. That is, you don’t declare a new scope my_scope separately. You just write
Notation "x <<< y" := (f x y) (at level 100, no associativity) : my_scope.
and that declares a new scope my_scope.
The answers for this question only apply to older versions of Coq. I'm not sure when it started but in at least Coq 8.13.2, Coq prefers the user to first use Declare Scope create a new scope. What the OP has in their code is Coq's preferred way to declare scopes now.
See the current manual