Pattern matching with a record in Oz - emacs

i'm having some trouble wrapping my head on how to utilize the elements of a record in Oz with pattern matching. Below is my code
declare
fun {Eval X E}
case X
of int(N) then N
[] var(X) then E.X
[] mul(X Y) then X*Y
[] add(X Y) then X+Y
end
end
end
{Eval add(var(a) mul(int(3) var(b))) env(a:2 b:4)}
This is the input I have to utilize, the var(a) is supposed to return 2, (and var(b) return 4) from the env record in the input, I just cannot figure it out for anything.

In your code, you need to call Eval recursively whenever you haven't reached a number or var. Try this instead:
declare
fun {Eval Node Env}
if {IsNumber Node} then Node
else
case Node
of var(X) then Env.X
[] mul(X Y) then {Eval X Env} * {Eval Y Env}
[] add(X Y) then {Eval X Env} + {Eval Y Env}
end
end
end
Additionally, Oz requires the return value of functions to be bound to a variable, so try something like:
declare
Ans = {Eval add(var(a) mul(3 var(b))) env(a:2 b:4)}
You can then view Ans with the Browser to verify the code is correct.

Related

Expression Evaluation Oz/Mozart

I am trying to create a function that takes an expression and evaluates it. Expressions can contain the following operations:
Integers - described by a tuple int(N), where N is an integer.
Addition - described by a tuple add(X Y), where both X and Y are arithmetic expressions.
Multiplication - described by a tuple mul(X Y), where both X and Y are arithmetic
expressions.
Variables - described by a tuple var(A), where A is an atom giving the variable name
An environment - described by a record env(a:5 b:5), where a and b are variables with values of 5.
For example: {Eval add(var(a) mul(int(3) var(b))) env(a:5 b:5)}. Which should evaluate to 20.
So far, I have implemented integers, addition, and multiplication. But I'm not really sure where to start for the variables and the environment.
My current code:
fun {Eval X}
case X of int(N) then N
[] add(X Y) then {Eval X} + {Eval Y}
[] mul(X Y) then {Eval X} * {Eval Y}
end
end
You need to get the value of the variable from the environment. This can be done by passing the env() as parameter to the Eval function, in order to access it from inside.
I have solved it for you. It should be easy to understand.
fun {Eval Statements Env}
case Statements of int(N) then N
[] add(X Y) then {Eval X Env} + {Eval Y Env}
[] mul(X Y) then {Eval X Env} * {Eval Y Env}
[] var(X) then Env.X
end
end
As a side note, this is practically how a common interpreter runs a programming script. By using statement stack and environment to store variable mappings.

The Hilbert epsilon operator

Why you can use the Hilbert epsilon operator in a method and in a function, but not in a "function method"?
method choose<T>(s:set<T>) returns (x:T)
requires s != {}
{
var z :| z in s;
return z;
}
function choose'<T>(s:set<T>):T
// function method choose'<T>(s:set<T>):T // Activate this line and comment the previous line to see the error
requires s != {}
{
var z :| z in s;
z
}
In order for the Hilbert epsilon operator, also known in Dafny as the let-such-that expression,
var z :| P; E
to be compilable, the constraint P must determine z uniquely. In your case, the constraint P is z in s, which does not determine z uniquely except for singleton sets.
If s were of type set<int>, you can (inefficiently) live up to this requirement by changing your choose' function to:
function method choose'<T>(s:set<int>):int
requires s != {}
{
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
Almost. You need to convince Dafny there is such a z. You can do that in a lemma. Here's a probably-longer-than-necessary-but-the-first-thing-I-got-working lemma that does that. Note that the lemma also uses the Hilbert operator, but in a statement context, so the uniqueness requirement does not apply.
function method choose'<T>(s:set<int>):int
requires s != {}
{
HasMinimum(s);
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
lemma HasMinimum(s: set<int>)
requires s != {}
ensures exists z :: z in s && forall y :: y in s ==> z <= y
{
var z :| z in s;
if s == {z} {
// the mimimum of a singleton set is its only element
} else if forall y :: y in s ==> z <= y {
// we happened to pick the minimum of s
} else {
// s-{z} is a smaller, nonempty set and it has a minimum
var s' := s - {z};
HasMinimum(s');
var z' :| z' in s' && forall y :: y in s' ==> z' <= y;
// the minimum of s' is the same as the miminum of s
forall y | y in s
ensures z' <= y
{
if
case y in s' =>
assert z' <= y; // because z' in minimum in s'
case y == z =>
var k :| k in s && k < z; // because z is not minimum in s
assert k in s'; // because k != z
}
}
}
Unfortunately, the type of your s is not set<int>. I don't know how to get a unique value from a general set. :(
For information about why the uniqueness requirement is important in compiled expressions see this paper.
Rustan

How to convert logical conditions to a variable of a function

I would like to achieve the above for the following:
Rn = 0.009; % Resolution of simulation (in m^3)
Xs = -1 : Rn : 1;
Ys = -1 : Rn : 1;
Zs = 0 : Rn : 1;
[X Y Z] = meshgrid(Xs, Ys, Zs);
alpha = atan2(Z,X);
ze = x.^2 + y.^2; % define some condition
m = 0.59; % manual input
cond = (pi/3 <= alpha) & ...
(alpha <= (2*pi/3)) & ...
(m <= Z) & ...
(Z <= ze); % more conditions
xl = nnz(cond); % the number of non-zero elements
f = abs(xl*1000 - 90) % guessing m to get f as low as possible
How do I turn m into a variable for some f function so I can call fminsearch to quickly find the corresponding m for f ≈ 0?
In order to use m as a variable, you need to define a function handle. So you need to write:
cond = #(m) ((pi/3) <= alpha) & (alpha <= (2*pi/3)) & (m <= Z) & (Z <= ze);
However, you cannot use a function handle in the nnz routine, since it only accepts matrices as inputs. But, the solution to the problem is that you only have Boolean variables in cond. This means, you can simply sum over cond and get the same result as with nnz.
The only issue I see is how to implement the sum in fminsearch. Unfortunately, I do not have access to fminsearch, however I would assume that you can do something with reshape and then multiply with dot (i.e. .*) with the unity vector to get a sum. But you'll have to try that one out, not sure about it.

Trapezodial Rule Matlab

I am completing an assignment for a class. We were to follow a flow chart to find the values for the trap rule code. I believe the problem is with my main code.
I am not sure if there is a problem with my function code or my main code, any help would be appreciated.
when I run the section, it display the function as the answer
The following is my mainscript code:
f = #(x) (4*sin (x)) / (exp(2*x)) ;
trap_haskell(f , 0 , 3 , 7)
The rest is my trapezoidal rule code
function [f] = trap_haskell(f, a, b, n)
x = a ;
h = (b - a) / n ;
s = f (a) ;
for k=1:1:n-1
x = x + h ;
s = s + 2 * f(x) ;
end
s = s + f(b) ;
I = (b - a) * s / (2 * n) ;
end
You're returning f as the output argument of trap_haskell which is the input function into trap_haskell itself. The variable I in your code actually stores the integral so it's simply a matter of changing the output variable of the function definition to return the integral instead:
%// ------ Change here
%// |
%// V
function [I] = trap_haskell(f, a, b, n)

Jacobian using in Maple

How can I use the Jacobian written below as function from (x, y) ?
g := (x, y) -> x - y
u := (x, y) -> x^2 + y^2
J := jacobian([g(x, y), u(x, y)], [x, y]);
My idea was to make funcion like this
Jf := (u, v) -> subs(x = u, y = v, J(x, y))
but it returns ugly matrix with brakets inside.
P. S. I use Maple 17
The linalg package (which exports the jacobian command) and lowercase matrix are deprecated. Use LinearAlgebra and Matrix instead, and VectorCalculus:-Jacobian.
Also, note the use of unapply.
restart:
g := (x, y) -> x - y:
u := (x, y) -> x^2 + y^2:
J:=VectorCalculus:-Jacobian([g(x,y),u(x,y)],[x,y]);
[ 1 -1 ]
J := [ ]
[2 x 2 y]
Jf:=unapply(J,[x,y]):
Jf(1,1);
[1 -1]
[ ]
[2 2]
Jf(s,t);
[ 1 -1 ]
[ ]
[2 s 2 t]