OCaml - Rejecting negative numbers - while-loop

I want to create a program that sums two ints. However, they must be both positive.
I wanted to write something like this:
let n = read_int ()
while n<=0 do
let n = read_int ()
done
So it would read the number again, until it checks that it's positive.
What is the correct way to do this?

To add to the other answers, a recursive function that would do the job would look like
let rec read_next_non_negative_int () =
let n = read_int () in
if n < 0 then
read_next_non_negative_int ()
else
n
Let's figure out how it works. It reads an integer n. If n is negative, that's no good, so we try the whole thing again. However otherwise, we have found a non-negative n so we just return it.
This is a very basic example of a recursive function. Recursive functions always have :
A call to the function itself inside their own definition. Here, it's in the then clause of our test.
An recursion termination, which is basically a return statement in many languages, but in OCaml you don't explicitly writes return. Here, it's the n in the else statement.
Without a self-call, the function wouldn't be recursive, and without recursion termination, it would loop forever. So when trying to write a recursive function, always think "What's the scenario in which there is no need to call the function again", and write that as your recursion termination(s). Then think "And when is it that I need to call my function again, and with which parameter", and write the self-call(s).

Your code isn't syntactically valid, but even if it were valid it's based on the idea of changing the value of a variable, which isn't possible in OCaml.
In imperative programming you can change the value of n until it looks like what you want. However, OCaml is a functional language and its variables are bound to one value permanently.
The n that appears in while n < = ... is not the same n that appears in let n = read_int (). The keyword let introduces a new local variable.
It might help to imagine writing a recursive function that returns the next non-negative value that it reads in using read_int. If it doesn't get a good value, it can call itself recursively.

Related

Return highest or lowest value Z notation , formal method

I am new to Z notation,
Lets say I have a function f defined as X |--> Y ,
where X is string and Y is number.
How can I get highest Y value in this function? Does 'loop' exist in formal method so I can solve it using loop?
I know there is recursion in Z notation, but based on the material provided, I only found it apply in multiset or bag, can it apply in function?
Any extra reference application of 'loop' or recursion application will be appreciated. Sorry for my English.
You can just use the predefined function max that takes a set of integers as input and returns the maximum number. The input values here are the range (the set of all values) of the function:
max(ran(f))
Please note that the maximum is not defined for empty sets.
Regarding your question about recursion or loops: You can actually define a function recursively but I think your question aims more at a way to compute something. This is not easily expressed in Z and this is IMO a good thing because it is used for specifications and it is not a programming language. Even if there wouldn't be a max or ran function, you could still specify the number m you are looking for by:
\exists s:String # (s,m):f /\
\forall s2:String, i2:Z # (s2,i2):f ==> i2 <= m
("m is a value of f, belonging to an s and all other values i2 of f are smaller or equal")
After getting used to the style it is usually far better to understand than any programming language (except your are trying to describe an algorithm itself and not its expected outcome).#
Just for reference: An example of a recursive definition (let's call it rmax) for the maximum would consist of a base case:
\forall e:Z # rmax({e}) = e
and a recursive case:
\forall e:Z; S:\pow(Z) #
S \noteq {} \land
rmax({e} \cup S) = \IF e > rmax(S) \THEN e \ELSE rmax(S)
But note that this is still not a "computation rule" of rmax because e in the second rule can be an arbitrary element of S. In more complex scenarios it might even be not obvious that the defined relation is a function at all because depending on the chosen elements different results could be computed.

Calculating the expected running time of function

I have a question about calculating the expected running time of a given function. I understand just fine, how to calculate code fragments with cycles in them (for / while / if , etc.) but functions without them seems a bit odd to me. For example, lets say that we have the following code fragment:
public void Add(T item)
{
var newArr = new T[this.arr.Length + 1];
Array.Copy(this.arr, newArr, this.arr.Length);
newArr[newArr.Length - 1] = item;
this.arr = newArr;
}
If my logic works correctly, the function Add has a complexity of O(1), because in the best/worst/average case it will just read every line of code once, right?
You always have to consider the time complexity of the function calls, too. I don't know how Array.Copy is implemented, but I'm going to guess it's O(N), making the whole Add function O(N) as well. Your intuition is right, though - the rest of it is in fact O(1).
If you have multiple sub-operations with O(n) + O(log(n)) etc and the costliest step is the cost of the whole operation - by default big O refers to the worst case. Here as you copy the array, it is an O(n) operation
Complexity is calculated following this 2 rules :
-Calling a method (complexity+ 1)
-Encountering the following keywords : if, while, repeat, for, &&, ||, catch, case, etc … (complexity+ 1)
In your case , given you are trying to copy an array and not a single value , the algorithm will complete N copy operations giving you an O(N) operation.

Make interpreter execute faster

I've created an interprter for a simple language. It is AST based (to be more exact, an irregular heterogeneous AST) with visitors executing and evaluating nodes. However I've noticed that it is extremely slow compared to "real" interpreters. For testing I've ran this code:
i = 3
j = 3
has = false
while i < 10000
j = 3
has = false
while j <= i / 2
if i % j == 0 then
has = true
end
j = j+2
end
if has == false then
puts i
end
i = i+2
end
In both ruby and my interpreter (just finding primes primitively). Ruby finished under 0.63 second, and my interpreter was over 15 seconds.
I develop the interpreter in C++ and in Visual Studio, so I've used the profiler to see what takes the most time: the evaluation methods.
50% of the execution time was to call the abstract evaluation method, which then casts the passed expression and calls the proper eval method. Something like this:
Value * eval (Exp * exp)
{
switch (exp->type)
{
case EXP_ADDITION:
eval ((AdditionExp*) exp);
break;
...
}
}
I could put the eval methods into the Exp nodes themselves, but I want to keep the nodes clean (Terence Parr saied something about reusability in his book).
Also at evaluation I always reconstruct the Value object, which stores the result of the evaluated expression. Actually Value is abstract, and it has derived value classes for different types (That's why I work with pointers, to avoid object slicing at returning). I think this could be another reason of slowness.
How could I make my interpreter as optimized as possible? Should I create bytecodes out of the AST and then interpret bytecodes instead? (As far as I know, they could be much faster)
Here is the source if it helps understanding my problem: src
Note: I haven't done any error handling yet, so an illegal statement or an error will simply freeze the program. (Also sorry for the stupid "error messages" :))
The syntax is pretty simple, the currently executed file is in OTZ1core/testfiles/test.txt (which is the prime finder).
I appreciate any help I can get, I'm really beginner at compilers and interpreters.
One possibility for a speed-up would be to use a function table instead of the switch with dynamic retyping. Your call to the typed-eval is going through at least one, and possibly several, levels of indirection. If you distinguish the typed functions instead by name and give them identical signatures, then pointers to the various functions can be packed into an array and indexed by the type member.
value (*evaltab[])(Exp *) = { // the order of functions must match
Exp_Add, // the order type values
//...
};
Then the whole switch becomes:
evaltab[exp->type](exp);
1 indirection, 1 function call. Fast.

matlab subsref: {} with string argument fails, why?

There are a few implementations of a hash or dictionary class in the Mathworks File Exchange repository. All that I have looked at use parentheses overloading for key referencing, e.g.
d = Dict;
d('foo') = 'bar';
y = d('foo');
which seems a reasonable interface. It would be preferable, though, if you want to easily have dictionaries which contain other dictionaries, to use braces {} instead of parentheses, as this allows you to get around MATLAB's (arbitrary, it seems) syntax limitation that multiple parentheses are not allowed but multiple braces are allowed, i.e.
t{1}{2}{3} % is legal MATLAB
t(1)(2)(3) % is not legal MATLAB
So if you want to easily be able to nest dictionaries within dictionaries,
dict{'key1'}{'key2'}{'key3'}
as is a common idiom in Perl and is possible and frequently useful in other languages including Python, then unless you want to use n-1 intermediate variables to extract a dictionary entry n layers deep, this seems a good choice. And it would seem easy to rewrite the class's subsref and subsasgn operations to do the same thing for {} as they previously did for (), and everything should work.
Except it doesn't when I try it.
Here's my code. (I've reduced it to a minimal case. No actual dictionary is implemented here, each object has one key and one value, but this is enough to demonstrate the problem.)
classdef TestBraces < handle
properties
% not a full hash table implementation, obviously
key
value
end
methods(Access = public)
function val = subsref(obj, ref)
% Re-implement dot referencing for methods.
if strcmp(ref(1).type, '.')
% User trying to access a method
% Methods access
if ismember(ref(1).subs, methods(obj))
if length(ref) > 1
% Call with args
val = obj.(ref(1).subs)(ref(2).subs{:});
else
% No args
val = obj.(ref.subs);
end
return;
end
% User trying to access something else.
error(['Reference to non-existant property or method ''' ref.subs '''']);
end
switch ref.type
case '()'
error('() indexing not supported.');
case '{}'
theKey = ref.subs{1};
if isequal(obj.key, theKey)
val = obj.value;
else
error('key %s not found', theKey);
end
otherwise
error('Should never happen')
end
end
function obj = subsasgn(obj, ref, value)
%Dict/SUBSASGN Subscript assignment for Dict objects.
%
% See also: Dict
%
if ~strcmp(ref.type,'{}')
error('() and dot indexing for assignment not supported.');
end
% Vectorized calls not supported
if length(ref.subs) > 1
error('Dict only supports storing key/value pairs one at a time.');
end
theKey = ref.subs{1};
obj.key = theKey;
obj.value = value;
end % subsasgn
end
end
Using this code, I can assign as expected:
t = TestBraces;
t{'foo'} = 'bar'
(And it is clear that the assignment work from the default display output for t.) So subsasgn appears to work correctly.
But I can't retrieve the value (subsref doesn't work):
t{'foo'}
??? Error using ==> subsref
Too many output arguments.
The error message makes no sense to me, and a breakpoint at the first executable line of my subsref handler is never hit, so at least superficially this looks like a MATLAB issue, not a bug in my code.
Clearly string arguments to () parenthesis subscripts are allowed, since this works fine if you change the code to work with () instead of {}. (Except then you can't nest subscript operations, which is the object of the exercise.)
Either insight into what I'm doing wrong in my code, any limitations that make what I'm doing unfeasible, or alternative implementations of nested dictionaries would be appreciated.
Short answer, add this method to your class:
function n = numel(obj, varargin)
n = 1;
end
EDIT: The long answer.
Despite the way that subsref's function signature appears in the documentation, it's actually a varargout function - it can produce a variable number of output arguments. Both brace and dot indexing can produce multiple outputs, as shown here:
>> c = {1,2,3,4,5};
>> [a,b,c] = c{[1 3 5]}
a =
1
b =
3
c =
5
The number of outputs expected from subsref is determined based on the size of the indexing array. In this case, the indexing array is size 3, so there's three outputs.
Now, look again at:
t{'foo'}
What's the size of the indexing array? Also 3. MATLAB doesn't care that you intend to interpret this as a string instead of an array. It just sees that the input is size 3 and your subsref can only output 1 thing at a time. So, the arguments mismatch. Fortunately, we can correct things by changing the way that MATLAB determines how many outputs are expected by overloading numel. Quoted from the doc link:
It is important to note the significance of numel with regards to the
overloaded subsref and subsasgn functions. In the case of the
overloaded subsref function for brace and dot indexing (as described
in the last paragraph), numel is used to compute the number of
expected outputs (nargout) returned from subsref. For the overloaded
subsasgn function, numel is used to compute the number of expected
inputs (nargin) to be assigned using subsasgn. The nargin value for
the overloaded subsasgn function is the value returned by numel plus 2
(one for the variable being assigned to, and one for the structure
array of subscripts).
As a class designer, you must ensure that the value of n returned by
the built-in numel function is consistent with the class design for
that object. If n is different from either the nargout for the
overloaded subsref function or the nargin for the overloaded subsasgn
function, then you need to overload numel to return a value of n that
is consistent with the class' subsref and subsasgn functions.
Otherwise, MATLAB produces errors when calling these functions.
And there you have it.

LINQ statement where result count is used in expression's condition

O' LINQ-fu masters, please help.
I have a requirement where I have to add items into a List(Of T) (let's call it Target) from an IEnumerable(Of T) (let's call it Source) using Target.AddRange() in VB.NET.
Target.AddRange(Source.TakeWhie(Function(X, Index) ?))
The ? part is a tricky condition that is something like: As long as the as yet unenumerated count is not equal to what is needed to fill the list to the minimum required then randomly decide if the current item should be taken, otherwise take the item.
Somethig like...
Source.Count() - Index = _minimum_required - _curr_count_of_items_taken _
OrElse GetRandomNumberBetween1And100() <= _probability_this_item_is_taken
' _minimum_required and _probability_this_item_is_taken are constants
The confounding part is that _curr_count_of_items_taken needs to be incremented each time the TakeWhile statement is satisfied. How would I go about doing that?
I'm also open to a solution that uses any other LINQ methods (Aggregate, Where, etc.) instead of TakeWhile.
If all else fails then I will go back to using a good old for-loop =)
But hoping there is a LINQ solution. Thanks in advance for any suggestions.
EDIT: Good old for-loop version as requested:
Dim _source_total As Integer = Source.Count()
For _index As Integer = 0 To _source_total - 1
If _source_total - _index = MinimumRows - Target.Count _
OrElse NumberGenerator.GetRandomNumberBetween1And100 <= _possibility_item_is_taken Then
Target.Add(Source(_index))
End If
Next
EDITDIT:
David's no-side-effects answer comes closes to what I need while staying readable. Maybe he's the only one who could understand my poorly communicated pseudo-code =). The OrderBy(GetRandomNumber) is brilliant in hindsight. I just need to change the Take(3) part to Take(MinimumRequiredPlusAnOptionalRandomAmountExtra) and drop the OrderBy and Select at the end. Thanks to the rest for suggestions.
You need to introduce a side-effect, basically.
In C# this is relatively easy - you can use a lambda expression which updates a captured variable. In VB this may still be possible, but I wouldn't like to guess at the syntax. I don't quite understand your condition (it sounds a little backwards) but you could do something like:
The C# would be something like:
int count = 0;
var query = source.TakeWhile(x => count < minimumRequired ||
rng.Next(100) < probability)
.Select(x => { count++; return x; });
target.AddRange(query);
The count will be incremented each time an item is actually taken.
Note that I suspect you actually want Where instead of TakeWhile - otherwise the first time the rng gives a high number, the sequence will end.
EDIT: If you can't use side-effects directly you may be able to use a horrible hack. I haven't tried this, but...
public static T Increment<T>(ref int counter, T value)
{
counter++;
return value;
}
...
int count = 0;
var query = source.TakeWhile(x => count < minimumRequired ||
rng.Next(100) < probability)
.Select(x => Increment(ref count, x));
target.AddRange(query);
In other words, you put the side-effect into a separate method, and call the method using pass-by-reference for the counter. No idea if it would work in VB, but possibly worth a try. On the other hand, a loop might be simpler...
As a completely different way of approaching it, is your source an in-memory collection already, which you can iterate through cheaply? If so, just use:
var query = Enumerable.Concat(source.Take(minimumRequired),
source.Skip(minimumRequired)
.TakeWhile(condition));
In other words, definitely grab the first n elements, and then start again, skip the first n elements and take the rest based on the condition.
If your task is to extract 3 random images from a collection of 50 random images, this works great.
target.AddRange( source.OrderBy(GetRandomNumber).Take(3) );
If you require order preservation, that's not too hard to add:
target.AddRange( source
.Select( (x, i) => new {x, i})
.OrderBy(GetRandomNumber)
.Take(3)
.OrderBy( z => z.i)
.Select( z => z.x)
);
If requirements are to (for whatever reason)
favor items at the end of the list
allow more items through than requested (5 instead of 3, but only sometimes)
then I'd write the foreach loop.