enum sup;
sup=['a','b','c'];
enum sup2;
sup2=['d','e','f'];
enum sup3;
sup3=sup++sup2;
I want to get an new enumerated type sup3 with all a,b,c,d,e,f.Is there any way in minizinc we can do this.
The short answer is no, this is currently not supported. The main issue with the concatenation of enumerated types comes from the fact we are not just concatenating two lists of things, but we are combining types. Take your example:
enum sup = {A, B, C};
enum sup2 = {D, E, F};
enum sup3 = sup ++ sup2;
When I now write E somewhere in an expression, I no longer know if it has type sup2 or sup3. As you might imagine, there is no guarantee that E would have the same value (for the solver) in the two enumerated types, so this can be a big problem.
To shine a glimmer of hope, the MiniZinc team has been working on a similar approach to make this possible (but not yet formally announced). Instead of your syntax, one would write:
enum X = {A, B, C};
enum Y = {D, E, F} ++ F(X);
The idea behind this is that F(X) now gives a constructor for the usage of X in Y. This means that if we see just A, we know it's of type X, but if we see F(A), then it's of type Y. Again, this is not yet possible, but will hopefully end up in the language soon.
More of a comment but here is my example of my need. When doing code coverage and FSM transition analysis I am forced to use exclusion to not analyze some transitions for the return_to_state, in the code below. If instead I could use concatenated types as shown, I would have more control over the tools reporting missing transitions.
type Read_states is (ST1);
type Write_states is (ST2, ST3, ST4);
type SPI_states is (SPI_write);
type All_States is Read_states & Write_states & SPI_states;
I could make return_to_state of type Write_states and FRAM_state of type All_states and then not have to put in exclusions in my FSM analysis.
Related
In following examples z3 assumes that 2 symbols with same name are equal.
solve(Int('z')<Int('z'))
returns: "no solution"
from z3 import *
x1=Int('x')
x2=Int('x')
x3=Int('x')
solve(x1*x2*x3==27)
returns:"[x = 3]"
Can I assume that z3 always treats symbols with same name and type as equals? For example if I have an equation with variable Int type variable z - can replace "z" with "Int('z')" everywhere in the equation and be sure that output will be the same?
Can I assume that z3 always treats function-symbols with same name and same type of arguments as equals like in following example:
S1 = DeclareSort('S1')
S2 = DeclareSort('S2')
x1=Const("x",S1)
x2=Const("x",S2)
f1=Function('F', S1, S1,S2,IntSort())
f2=Function('F', S1, S1,S2,IntSort())
solve(f1(x1,x1,x2)<f2(x1,x1,x2))
returns:"no solution"
Can I assume that z3 never treats function-symbols with same name, but different type or number of arguments as equals like in following example:
S1 = DeclareSort('S1')
S2 = DeclareSort('S2')
x1=Const("x",S1)
x2=Const("x",S2)
f1=Function('F', S1, S1,S2,IntSort())
f2=Function('F', S1, S2,S2,IntSort())
solve(f1(x1,x1,x2)<f2(x1,x2,x2))
returns:"
[x = S2!val!0,
x = S1!val!0,
F = [else -> 1],
F = [else -> 0]]
"
In Z3 variables are identified by name and sort. So, if two variables have the same name and sort then they are the same. Correspondingly, if they either have different names OR sorts, then they are different. The sort is the type and for function names the type is a function type. (i.e. there’s no special treatment for function names. You can think of ordinary variables as functions that take 0 arguments.)
In particular, two different variables can have the same name so long as they have different sorts. This can be rather confusing, however, since when z3 prints the corresponding SMTLib or models, you won’t have an obvious indication showing which one is which. So I’d advise against using the same name even if the sorts differ.
I wrote the following code block in Alloy:
one h: Human | h in s.start => {
s'.currentCall = h.from
}
I want to pick one 'human' from a set of humans (s.start) and set a variable (s'.currentCall) equal to h.from.
However I think this code is saying: There is only one human in s.start, where
s'.currentCall = h.from
is true.
Is my assumption correct? And how should I fix this?
You are absolutely correct, the meaning of the one quantifier is that there is exactly one element in the given domain (set) such that the quantifier body holds true.
Regarding your original goal of picking one element from a set and setting its field value to something: that sounds like an imperative update, and you can't really do that directly in Alloy; Alloy is fully declarative, so you can only assert logical statements about the sets and relations for a bounded universe of discourse.
If you just change one to some and also change the implication to conjunction, and then run the analysis (a simple run command to find a valid instance), the Alloy Analyzer will find a model in which the value s'.currentCall is equal to h.from for some (arbitrary) h from s.start:
pred p[s, s': S] {
some h: s.start | s'.currentCall = h.from
}
run p
I hope this is what you want to achieve.
Consider this:
module Module1 =
type A() = class end
type B() = inherit A()
type C() = inherit A()
let f x = if x > 0 then new B() else new C()
The last line yields an error about type B being expected, but type C being found instead.
Ok, I can pretend to understand that: the compiler doesn't know which common base to infer in case there are many.
But guess what? Even when I specify the function type, it still doesn't work:
let f x : A = if x > 0 then new B() else new C()
Now this gives me two errors: "A expected, B found" and "A expected, C found".
WTF? Why can't it see that both B and C are implicitly convertible to A?
Yes, I do know that I could use upcast, like so:
let f x : A = if x > 0 then upcast new B() else upcast new C()
But guess what (again)? upcast only works in the presence of the explicit function type declaration!
In other words, this:
let f x = if x > 0 then upcast new B() else upcast new C()
still gives an error.
WTF?! Do I really have to add 50% of noise to my program just to help the compiler out?
What's with all that hype about F# code being clean and noiseless?
Somehow it feels like this cannot be true.
So the question is: am I missing something? How do I make this both compact and working?
Type inference and subtyping do not play well together, as Carsten's links discuss to some extent. It sounds like you are unhappy with F#'s approach and would prefer it if
if b then
e1
else
e2
were implicitly treated more like
if b then (e1 :> 'a) else (e2 :> 'a)
with the compiler additionally inferring 'a to be the least upper bound in the type hierarchy based on the types that would otherwise be inferred for e1 and e2.
It might be technically possible to do this, and I can't definitively speak to why F# doesn't work this way, but here's a guess: if if statements behaved this way then it would never be an error to have different types in the if and else branches, since they could always be unified by implicitly upcasting them to obj. However, in practice this is almost always a programmer error - you almost always want the types to be the same (e.g. if I return a character from one branch and a string from the other, I probably meant to return strings from both, not obj). By implicitly upcasting, you would merely make the presence of these errors harder to find.
Furthermore, it's relatively rare in F# to deal with complicated inheritance hierarchies, except perhaps when interoperating with other .NET code. As a result, this is a very minor limitation in practice. If you're looking for a syntactically shorter solution than upcast, you might try :> _, which will work as long as there is something to constrain the type (either an annotation on the overall result, or a specific cast on one of the branches).
there is a reason for all of this but to make it short: F# is more strong typed than C# so you have to tell where to cast to (see here):
let f x = if x > 0 then (new B() :> A) else (new C() :> A)
Here you can find further information: F# need for cast
And here is another great discussion on this.
What is the best way to define a numerical constant in Mathematica?
For example, say I want g to be the approximate acceleration due to gravity on the surface of the Earth. I give it a numerical value (in m/s^2), tell Mathematica it's numeric, positive and a constant using
Unprotect[g];
ClearAll[g]
N[g] = 9.81;
NumericQ[g] ^= True;
Positive[g] ^= True;
SetAttributes[g, Constant];
Protect[g];
Then I can use it as a symbol in symbolic calculations that will automatically evaluate to 9.81 when numerical results are called for. For example 1.0 g evaluates to 9.81.
This does not seem as well tied into Mathematica as built in numerical constants. For example Pi > 0 will evaluate to True, but g > 0 will not. (I could add g > 0 to the global $Assumptions but even then I need a call to Simplify for it to take effect.)
Also, Positive[g] returns True, but Positive[g^2] does not evaluate - compare this with the equivalent statements using Pi.
So my question is, what else should I do to define a numerical constant? What other attributes/properties can be set? Is there an easier way to go about this? Etc...
I'd recommend using a zero-argument "function". That way it can be given both the NumericFunction attribute and a numeric evaluation rule. that latter is important for predicates such as Positive.
SetAttributes[gravUnit, NumericFunction]
N[gravUnit[], prec_: $MachinePrecision] := N[981/100, prec]
In[121]:= NumericQ[gravitUnit[]]
Out[121]= True
In[122]:= Positive[gravUnit[]^2 - 30]
Out[122]= True
Daniel Lichtblau
May be I am naive, but to my mind your definitions are a good start. Things like g > 0->True can be added via UpValues. For Positive[g^2] to return True, you probably have to overload Positive, because of the depth-1 limitation for UpValues. Generally, I think the exact set of auto-evaluated expressions involving a constant is a moving target, even for built-in constants. In other words, those extra built-in rules seem to be determined from convenience and frequent uses, on a case-by-case basis, rather than from the first principles. I would just add new rules as you go, whenever you feel that you need them. You probably can not expect your constants to be as well integrated in the system as built-ins, but I think you can get pretty close. You will probably have to overload a number of built-in functions on these symbols, but again, which ones those will be, will depend on what you need from your symbol.
EDIT
I was hesitating to include this, since the code below is a hack, but it may be useful in some circumstances. Here is the code:
Clear[evalFunction];
evalFunction[fun_Symbol, HoldComplete[sym_Symbol]] := False;
Clear[defineAutoNValue];
defineAutoNValue[s_Symbol] :=
Module[{inSUpValue},
s /: expr : f_[left___, s, right___] :=
Block[{inSUpValue = True},
With[{stack = Stack[_]},
If[
expr === Unevaluated[expr] &&
(evalFunction[f, HoldComplete[s]] ||
MemberQ[
stack,
HoldForm[(op_Symbol /; evalFunction[op, HoldComplete[s]])
[___, x_ /; ! FreeQ[Unevaluated[x], HoldPattern#expr], ___]],
Infinity
]
),
f[left, N[s], right],
(* else *)
expr
]]] /; ! TrueQ[inSUpValue]];
ClearAll[substituteNumeric];
SetAttributes[substituteNumeric, HoldFirst];
substituteNumeric[code_, rules : {(_Symbol :> {__Symbol}) ..}] :=
Internal`InheritedBlock[{evalFunction},
MapThread[
Map[Function[f, evalFunction[f, HoldComplete[#]] = True], #2] &,
Transpose[List ### rules]
];
code]
With this, you may enable a symbol to auto-substitute its numerical value in places where we indicate some some functions surrounding those function calls may benefit from it. Here is an example:
ClearAll[g, f];
SetAttributes[g, Constant];
N[g] = 9.81;
NumericQ[g] ^= True;
defineAutoNValue[g];
f[g] := "Do something with g";
Here we will try to compute some expressions involving g, first normally:
In[391]:= {f[g],g^2,g^2>0, 2 g, Positive[2 g+1],Positive[2g-a],g^2+a^2,g^2+a^2>0,g<0,g^2+a^2<0}
Out[391]= {Do something with g,g^2,g^2>0,2 g,Positive[1+2 g],
Positive[-a+2 g],a^2+g^2,a^2+g^2>0,g<0,a^2+g^2<0}
And now inside our wrapper (the second argument gives a list of rules, to indicate for which symbols which functions, when wrapped around the code containing those symbols, should lead to those symbols being replaced with their numerical values):
In[392]:=
substituteNumeric[{f[g],g^2,g^2>0, 2 g, Positive[2 g+1],Positive[2g-a],g^2+a^2,g^2+a^2>0,
g<0,g^2+a^2<0},
{g:>{Positive,Negative,Greater}}]
Out[392]= {Do something with g,g^2,True,2 g,True,Positive[19.62\[VeryThinSpace]-a],
a^2+g^2,96.2361\[VeryThinSpace]+a^2>0,g<0,a^2+g^2<0}
Since the above is a hack, I can not guarantee anything about it. It may be useful in some cases, but that must be decided on a case-by-case basis.
You may want to consider working with units rather than just constants. There are a few options available in Mathematica
Units
Automatic Units
Designer units
There are quite a few technical issues and subtleties about working with units. I found the backgrounder at Designer Units very useful. There are also some interesting discussions on MathGroup. (e.g. here).
A contrived example:
signature A =
sig
type t
val x: t
end
signature B =
sig
type t
val y: t
end
signature C = sig include A B end
Obviously, this will cause complaints that type t occurs twice in C. But is there any way to express that I want the two ts to be equated, ending up with:
signature C =
sig
type t
val x: t
val y: t
end
I tried all sorts of silly syntax like include B where type t = A.t, which unsurprisingly didn't work. Is there something I've forgotten to try?
Also, I know that this would be simply answered by checking the language's syntax for anything obvious (or a lack of), but I couldn't find a complete grammar anywhere on the internet.
(FWIW, the actual reason I'm trying to do this is Haskell-style monads and such, where a MonadPlus is just a mix of a Monad and an Alternative; at the moment I'm just repeating the contents of ALTERNATIVE in MONAD_PLUS, which strikes me as less than ideal.)
You're hosed. The best you can do is, as Jordan Lewis suggests, use substructures and a sharing clause. To include two different signatures that both define t is always an error. So mixing ALTERNATIVE and MONAD_PLUS in the way you would like just isn't going to work.
For a proposal of other things that are wrong with include and how to fix them, see An Expressive Language of Signatures.
You're looking for a sharing clause.
signature C =
sig
structure A1 : A
structure B1 : B
sharing type A1.t = B1.t
type t = A1.t
val z : t
end
This ensures that A1's t and B1's t are the same, and furthermore uses that same t as the type of a value z.
Standard ML '97's grammar is available here.