We all know that the DO loop is more powerful than the FORALL statement in Fortran. That is, you can always substitute a FORALL by a DO, but not vice versa.
What about the WHERE statement and block?
Can I always substitute the IF by a WHERE? Is it always possible to code the conditionals and bifurcations with a WHERE, thus avoiding the IF?
WHERE statements are reserved for arrays assignments and nothing else, e.g.:
INTEGER, DIMENSION(100,100) :: a, b
... define a ...
WHERE(a < 0)
b = 1
ELSEWHERE
b = 0
ENDWHERE
If you tried adding in something, say a WRITE statement, inside the WHERE block, you would see something like the following compiling error (compiler dependent):
Error: Unexpected WRITE statement in WHERE block at (1)
EDIT
Note that nested WHERE blocks are legal:
WHERE(a < 0)
WHERE( ABS(a) > 2)
b = 2
ELSEWHERE
b = 1
ENDWHERE
ELSEWHERE
b = 0
ENDWHERE
Related
I need to build a MILP (Mixed integer linear programming) constraint form this if-else statement:
with beta is a constant.
if (a > b) then c = beta else c = 0
How can I build the statement to MILP constraint. Are there any techniques for solving this problem. Thank you.
I am assuming that a, b, and c are all decision variables here. To build your constraint, you need to add a new binary variable -- let's call it x -- that will equal 1 if a > b and 0 otherwise. You also need a large constant M. Then add the following constraints:
Mx >= a - b
M(1-x) >= b - a
x in {0,1}
The logic is: If a > b, then x must equal 1 by the first constraint (and x may equal 1 by the second constraint). If b > a, then 1-x must equal 1 by the second constraint, i.e., x must equal 0 (and x may equal 0 by the first constraint).
Next, we need a constraint that says, if x = 1, then c = beta, otherwise, c = 0:
c = beta * x
Note: The logic above allows c to equal either 0 or beta if a = b; the solver will decide. Do you need c to equal 0 if a = b?
Another note: In "big-M"-type formulations like this one, it's always best to keep M as small as possible while maintaining the validity of the constraints. In this case, this means setting M to the largest possible (or plausible) difference between a and b. If your model is small, it won't matter much, but if you have lots of these decision variables, then it can matter a lot.
I am new to SML and I have written a program that takes 3 integer numbers (n,z,k) and wants to compare them with a value given in the program, if the statement is correct it will return true, else false. conditions and values should be equal simultaneously, I mean program will return true if all these numbers are equal to the value given in the program, so my if statement should check 3conditions at the same time.
my problem is that I don't know how I can write all these 3conditions in one if clause, because SML don't recognize for example & or ^ as and!
for example i want to check whether if(n==8 && k==5 && z==9). what should I use instead of &
here is the code:
fun EvalR (n: int , k: int , z:int) =
if (n=8 ???) then true
else false;
Since Ashkan Parsa referred to the CS317 SML Style Guide, I thought I would point out what you might derive from it.
Let function names start with a lower case, e.g. evalR.
Don't write if ... then true else false; simply write ....
Some disagree; type annotations certainly are helpful, but so is type inference.
As nazila says, the and operator in Standard ML is called andalso.
So,
fun evalR (n, k, z) =
n = 42 andalso k = 43 andalso z = 0
It might seem comfusing that the function body contains =s at the same time as the function being defined with a = to separate the function arguments from the function body. Just think of the latter =s as value operators and the first = as a part of declaring things (like types, values, functions, etc.)
I found it. we can use andalso in SML.
Why does this compile?
fun foo (h::t) =
h = hd(t);
But this does not
fun foo (h::t) =
PolyML.print (h::t);
print "\n";
h = hd(t);
?
Value or constructor (h) has not been declared Found near =( h, hd(t))
Value or constructor (t) has not been declared Found near =( h, hd(t))
Exception- Fail "Static errors (pass2)" raised
I think your frustration with the language prevents you from solving your problem(s) more than the limitations of the language. As I said in a previous answer, semicolons cannot be used like you used them. You need to wrap those statements inside parentheses:
fun foo (h::t) =
(
PolyML.print (h::t);
print "\n";
h = hd(t)
)
Furthermore, you first snippet doesn't need a semicolon:
fun foo (h::t) =
h = hd(t)
Here's the thing, in SML semicolons are not used to terminate statements, they're used to separate expressions. Think of ; as a binary operator, just like + or -. With the added constraint that you need parentheses around.
Also, you're probably using the = operator in the wrong way inside h = hd(t). It's not assignment, it's an equality check, just like == in other languages. If you want assignment, you need a ref type.
It's probably better to ask what exactly you're trying to solve, because at this point you're totally misunderstanding the syntax and semantics of SML and we can't really write a tutorial on in here.
I'm trying to write a simple Ocaml function but im getting this error:
Error: This expression has type unit
but an expression was expected of type int
let rec euclid a b =
if a = b then a
else if a < b then 1
else if a > b then 2
To fix the immediate problem, you need else clauses in your function:
let rec euclid a b =
if a = b then a
else if a < b then 1
else 2 (* You know a > b is the only possible alternative *)
You may realize this, but this function is not recursive, nor, I think, is it doing what you want it to do.
However, there is an error in the way you're conceptualizing how a function works in Ocaml. The way you've written the function is imperative in nature; it is a series of if/then statements which are acted upon sequentially. Rather, the return value of euclid should be simply the result of one broad if/then statement (an integer value). Nesting, as I have done above, can be acceptable, but the essential thing to take away is that a function is just a single expression which is evaluated, not a series of imperative actions.
EDIT for updated question:
All OCaml if/then statements should have else clauses. Your very last nested if/then statement has no else clause. If OCaml detects an if/then statement with no else clause, an else clause is assumed returning () (unit). Essentially, if a > b is false, what should OCaml return? It assumes nothing, but returning () conflicts with the supposed type of your function (an integer).
Of course, that a > b is false is impossible in your function, since if not a = b and not a < b, the only other choice is a > b. Thus, you don't need another if statement at the end of your function; at that point, you know without a doubt that a > b, so you can simply say else 2.
I am trying to write a code which checks if number is Fibonacci or not in ML. I am a beginner. Help me find out what is the problem with my code.
fun isfib(n :int): bool=
let
val a1=1;
val a2=1;
val temp=0;
in
while a2<n do (
a1=temp
a2=a1
a2=temp+a2
)
if a2=n then true
else false
end;
a1=temp
a2=a1
a2=temp+a2
= is the equality operator in SML, not an assignment operator. So the above code is just equivalent to this:
false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)
So you have three side-effect-free expressions in your loop, so it just won't do anything.
It's clear that you actually want to change the values of those variables, but you can't do that. Variables in SML are immutable - you can't change them after they're set. So even having a while condition like a2 < n doesn't make sense because a2 and n can't change, so the condition is either always true or always false. If you want to use a while loop like this, you should look into the ref type, which allows you to create mutable values that you can use to simulate mutable variables.
That said using while loops and mutation is not idiomatic SML. There's a reason why variables in SML aren't mutable: the language designers want to encourage you to not rely on mutation (and thus also not on while loops). The idiomatic way to loop in SML is to either use higher order functions (like map, filter, foldl etc.) or recursion. For your problem a recursive function would make the most sense.