Ocaml fixed point implementation - ocaml

I'm trying to figure out how to implement fixed point iteration in Ocaml. That is, given a function f and an x, I want to calculate what the final value of what f(f(f(x)...)) will be.
So for example, if my function is x/2 and my x=50, my answer should be 0.
So far, I have
let rec computed_fixed_point eq f x =
if (x == f x) then
x
else
computed_fixed_point eq f (f x)
This works for the function x/2 and x=50 (giving me 0), but for functions that go off to infinity or something other than 0, it doesn't seem to work.
Can another give me some advice? Thanks!

It's a little hard to understand the rationale of this problem. Not every function is going to have a fixed point. For example fun x -> (x + 1) mod 5. Not every function with a fixed point will reach the fixed point by repeated application from a distinct starting point. (I just did some googling, and fixed points like this are called "attractive fixed points".)
Here are some comments:
You shouldn't use ==, which is the physical equality operator. You possibly want to use =, equality of values.
However, I don't see what the eq parameter is for. Perhaps the caller is allowed to specify what equality to use. If so, you should use this instead of ==.

Related

Using a particular higher-order helper function to compute factorial

I'm taking a MOOC (no credit). One of the assigned problems is to write a factorial function using a function that follows this:
(’a->’a)->(’a->bool)->’a->’a
I've created that function:
fun do_until (f, g) = fn x => case g(f x) of
false => f x
| _ => do_until(f,g) (f x);
but I've had difficulty using my do_until function to implement factorial.
The solution should follow this format I believe:
fun factorial x = (do_until (f, g)) x
The problem I see is that the 'g' function can only validate the result, and if validated, then return that result. Since the function type descriptors are fairly restrictive, it limits you from passing in a tuple to g, then verifying off part of the tuple and returning the other part. ie. (factorial, int to mult) then g would verify from #2 and return #1. Unfortunately the types prevent that. I'm starting to think using do_until as a helper function is impossible unless you compute the factorial some other way and then 'g' would just compare your result to that. Please let me know if I'm wrong and where to go next!
You have the wrong type – the function should be curried – and you will probably have more luck if you give the parameters more descriptive names than "f" and "g":
fun do_until next done x = if done x
then x
else do_until next done (next x)
Note that you can pass anything from factorial to do_until – for instance a tuple that holds your computation state – and then "take it apart" once do_until is done. (I suspect that this is why you're stuck.)

if statement checking multiple conditions in SML

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.

Remove real element from list - SML

I have written the following code:
fun remove_element(nil, elem) = raise Empty
| remove_element(hd::tl, elem) = if(hd=elem) then tl else hd::remove_element(tl, elem);
but that function (which removed element elem from list) works for int. I need to make it work for real numbers, but I can't do it. I have tried a lot of ways of rewriting the function and also I used :real but these bring me errors.
Any suggestions?
Thank you
The accepted answer should have allowed you to finish your assignment, so I will show two other approaches for variations of your problem without worrying about doing your homework for you. As Kevin Johnson said, it isn't possible to directly compare two reals. It is possible to do so indirectly since a=b if and only if a<=b and b<=a. Often this is a bug, especially if the list in question is of numbers produced by numerical computations. But -- there are some situations where it makes sense to compare reals for equality so you should certainly be able to do so as long as you are clear that this is what you want. This leads to the following modification of your code:
fun remove_real([],x:real) = []
| remove_real(y::ys,x) =
if (y <= x andalso y >= x) then
remove_real(ys,x)
else
y::remove_real(ys,x);
A few points:
1) I changed it to remove all occurrences of the element from the list rather than just the first occurrence. This involved changing the basis case to returning the empty list since [] with y removed is just [] rather than an error situation. Also, rather than simply returning the tail if the element is found I return the recursive call applied to the tail to remove any additional occurrences later on. You could easily modify the code to make it closer to your original code.
2) I needed to put the explicit type annotation x:real so that SML could infer that the list was of type real list rather than type int list.
3) I replaced nil by [] for aesthetic reasons
4) I replaced your pattern hd::tl by y::ys. For one thing, hd and tl are built-in functions -- I see no reason to bind those identifiers to anything else, even if it is just local to a function definition. For another thing, the less visual clutter in a pattern the better.
5) I made more use of white space. Partially a matter of taste, but I think that fairly complicated clauses (like your second line) should be split across multiple lines.
If you want to go the route of including an error tolerance for comparing reals, I think that it makes most sense to include the tolerance as an explicit parameter. I find |x-y| < e to be more natural than two inequalities. Unfortunately, the built-in abs only applies to ints. If x - y is real then the expression
if x - y < 0.0 then y - x else x - y
returns the absolute value of x - y (it flips the sign in the case that it is neagative). As an added bonus -- the comparison with 0.0 rather than 0 is all that SML needs to infer the type. This leads to:
fun remove_elem([],x,tol) = []
| remove_elem(y::ys,x,tol) =
if (if x - y < 0.0 then y - x else x - y) < tol then
remove_elem(ys,x,tol)
else
y::remove_elem(ys,x,tol);
Typical output:
- remove_real([2.0, 3.1, 3.14, 3.145, 3.14], 3.14);
val it = [2.0,3.1,3.145] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.01);
val it = [2.0,3.1] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.001);
val it = [2.0,3.1,3.145] : real list
The issue is here: hd=elem
In languages like ML and Javascript, you cannot directly compare two reals as reals are bound to rounding errors.
You have to use a lambda range and define an interval instead. elem - lambda < hd andalso elem + lambda > hd

Variable types for parameters in SML

fun in_list (x : int, y : int list) =
if null y
then false
else if x=hd y then true
else in_list(x,tl y)
This is what my code currently looks like, it simply returns true if x appears in the the y list, false if not. The issue is I want it to be able to input "a" and ["a", "b", "c"] as well, or even have x be a list, and y be a list of lists. I am VERY new to ML (just started learning about it last week), and have searched for answers and cannot come up with anything.
If you change the first line to
fun in_list (x : ''a, y : ''a list) =
then it will behave as you want. Here ''a is an equality type variable that can stand for any type that supports the = operator.
You could also just leave out the types altogether and the most general correct type will be inferred.
Types can always be omitted in function declarations, with is only one exception: where overloading of operators could cause ambiguity. An example is
fun square x = x*x
because the type of x could be either int or real. (It will default to int, maybe not what you want.)
The point is that there is only one function hd. But the operator * can refer to two quite different functions.

Haskell Beginner: Currying/List Associativity

From Learn You a Haskell:
Think about this list: [5]. That’s just syntactic sugar for 5:[]. On
the left side of the :, there’s a value; on the right side, there’s a
list. In this case, it’s an empty list. Now how about the list [4,5]?
Well, that desugars to 4:(5:[]). Looking at the first :, we see that
it also has an element on its left side and a list, (5:[]), on its
right side.
The same goes for a list like 3:(4:(5:6:[])), which could be written
either like that or like 3:4:5:6:[] (because : is right-associative)
or [3,4,5,6].
For the bolded part, I was expecting the growing list to culminate in 3:(4:(5:(6:[]))). This has something to do with my lack of understanding of currying, associativity, or both. Can someone tell me the flaw in my thinking?
Multiplication is associative. This means that (x * y) * z is the same as x * (y * z). However, : is not associative.
However, the terms "left-associative" and "right-associative" are different, and unrelated to the term "associative".
If * is left-associative, then x * y * z is the same thing as (x * y) * z. The parentheses are redundant.
If * is right-associative, then x * y * z is the same thing as x * (y * z). The parentheses are redundant.
Currying has nothing to do with this.
Since : is right-associative, [3,4,5,6] can be written as:
3:(4:(5:(6:[])))
3:4:(5:(6:[]))
3:(4:5:(6:[]))
3:4:5:(6:[])
3:(4:(5:6:[]))
3:4:(5:6:[])
3:(4:5:6:[])
3:4:5:6:[]
It's just a typo. There should be a parenthesis in the example (but it is the same behaviour without one, because of the associativity).
You say "I was expecting the growing list to culminate in 3:(4:(5:(6:[])))".
Indeed you are right. If you want to eliminate all syntactic sugar from [3,4,5,6], you will get 3:(4:(5:(6:[])))
You are puzzled by the fact that as you state in the comment in your question "the book says 3:(4:(5:6:[]))".
Again, you are right to be. In the interest of keeping presentation uniform, it shouldn't; this was probably a typo.
As far as Haskell syntax and semantics go though, there is nothing wrong with writing 3:(4:(5:6:[])) instead of 3:(4:(5:(6:[]))). What this boils down to is the question of whether 5:6:[] is the same as 5:(6:[]) or not. By the definition of right-associativity it is. Because : is right associative x:y:z = x:(y:z).
Just to add a geeky note here: by taking advantage of :'s right-associativity (i.e. not using parentheses), one can write 3:(4:(5:(6:[]))) quite concisely: 3:4:5:6:[]. This is only a single character longer than its syntactically sugared [3,4,5,6].
See also: http://en.wikipedia.org/wiki/Operator_associativity for more info on associativity.