Encode if-branch and recursion in eager evaluation - if-statement

As far as I know, in eager evaluation we cannot encode the if-branch and recursion the same way as in normal-order evaluation.
For example, in lambda calculus if-branch and factorial(fac) can be encoded
if e1 e2 e3 = e1 e2 e3
fac = Y(λf.λn. if n=0 1 n*f(n-1))
Y = λf.(λx. f(xx))(λx. f(xx))
Can we encode the if-branch and recursion in eager evaluation?
If we can i like to know how should we encode if-branch and factorial in eager evaluation using lambda calculus.
if e1 e2 e3 = ???
fac = ???

wrap them both in a lambda that ignores its argument, then if can choose the branch by forcing it, passing in some dummy value.
So it can be done but only if 'if' is used like this: if e1 (λ_.e2) (λ_.e3)

Related

Avoid the warning "Warning 21: this statement never returns (or has an unsound type.)"

This is the first time that I met the following warning "Warning 21: this statement never returns (or has an unsound type.)" and I don't have an idea how to fix it.
let display_committers_stats response = match response##readyState with
| XmlHttpRequest.DONE ->
begin match response##status with
| 200 ->
Js_client_ui.create_menu_tabs "GitSearchTabs";
let l =
Json_parser.get_commits (Js.to_string response##responseText) in
let values =
Json_parser.group_commits_by_user l
|> List.map (fun (author, commits) ->
Js_data.create_discreteBar_item author (float_of_int commits))
|> Array.of_list
|> Js.array in
let discreteBar_chart =
Js_data.create_discreteBar_chart "Commits-impact" values in
let js_arr = Js.array ([|discreteBar_chart |]) in
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_discreteBar_chart")
[|
Js.Unsafe.inject ((js_arr))
|];
let js_arr =
l
|> List.mapi (fun i commit ->
Js_data.create_timeline_data i commit.Git_data.message
commit.Git_data.time)
|> Array.of_list
|> Js.array in
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_timeline")
[|
Js.Unsafe.inject ((js_arr))
|]
| _ -> Printf.printf "Unexcepted status\n" end
| _ -> Printf.printf "Unexcepted state\n"
The warning show the following line :
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_discreteBar_chart")
[|
Js.Unsafe.inject ((js_arr))
|];
For execute multiples expressions in Ocaml, I know that the issue is to use ; between the expressions but what's is wrong in my function now ? Can I have some tips ?
Try wrapping the call in ignore, i.e. instead of Js.Unsafe.fun_call ...;, ignore (Js.Unsafe.fun_call ...);.
The reason this is happening is because your JS function call has a result type "'b", which is not dependent on any of the argument types. In the OCaml type system, this typically means that the function doesn't return, because the only way to "produce" a value of an arbitrary type 'b from nothing is to raise an exception – that is, to give up trying to produce it.
The sequence expression (semicolon) e1; e2 means complete the first expression, then complete the second one. In this case, OCaml is worried that your e1 (the JS function call) won't complete because of its unconstrained result type, as explained above. That would make the sequence expression pointless, which is why you get the warning. However, we know that the reason e1 has an unconstrained result type isn't because it doesn't complete, but because we are using an unsafe binding to JS.
To get around this, wrap e1 in a call to ignore, which is a function that takes anything and evaluates to unit. Now, ; will "see" unit on its left instead of an unconstrained 'b.
Generally speaking, you always want to have an expression of type unit on the left of a ;. So, even if you have an expression that evaluates to a constrained type (such as a concrete type int or a type parameter that is mentioned in the argument types), if that type is not unit, you should still wrap that expression in ignore.

List.iter & List.fold_right used together

I am trying to use the fold_right and List.iter functions in the List module. Is there anyway to use them in conjunction with one another?
let step nfa start transition =
let transition_list = get_transition nfa in
List.iter ( fun state ->
List.fold_right (fun ct nl ->
if ((get_pre_trans transition)= state && (get_trans ct) = transition) then
(get_post_transition transition)::nl
else
nl
) transition_list []
) start
;;
** The get_xxx functions get values from a tuple where there is a pre-transition, transition value, and post-transition.
Return error:
Error: This expression has type 'a list but an expression was expected of type unit.
Not sure what to do.
The body of the function that you pass to iter contains only one expression, a call to fold_right, that evaluates to a value of type list, but iter signature requires you to pass a function, that returns a value of type unit. That is basically what compiler tries to say to you. If you're not interested in the value to which fold_right is evaluated, then you can ignore it using ignore function, that takes a value of any type and returns a value of type unit. On the other hand, if you don't want to discard it, then you shouldn't use iter, and use fold_right or, better, fold_left.
And, finally, answering your question, yes, there're ways to combine them together, but usually, if you're applying a fold inside iter, you're doing something wrong.

Check whether number is Fibonacci or not in Standard ML

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.

Postfix expression list evaluation

I have written a program to evaluate a post-fix expression in prolog recursively from an expression list. For example, given the following list:
[+,1,2]
It should return 3. They way I have constructed my predicate is to call itself recursively until it reaches the end of the list so that it reads values backwards. (the same as reading this list from left to right:[2,1,+]).
My problem is that when I try to return more than one value through the recursive calls all the values suddenly disappear.
Here's the code:
eval_list([Head|Tail],_,Result):-
Tail==[], % last element of list
Result=Head,
write(Head),
write(' was stored in Result!\n').
eval_list([Head|Tail],Store1,Result):-
eval_list(Tail,Store2, NewResult),
(\+integer(Store2))
->
% if no integer is bound to Store2, bind Store1 to Head
Store1=Head,
Result is NewResult,
write(Head),
write(' is stored value!\n')
; (integer(Store2)) ->
% if an integer is bound to store2, we perform operation specified by the Head with the stored number
X is Store2+NewResult,
Result is X,
write('performed operation!\n')
;
% if doesnt catch either of these states the program is broken
( print('something broke\n'),
print(Store1),
nl,
print(Store2),
nl,
print(Head),
nl,
print(Result),
nl
).
I get the following output:
?- eval_list([+,1,2],X,Result).
2 was stored in Result!
1 is stored value!
something broke
_G1162
_L147
+
_G1163
true.
I don't understand why my values disappear, or if there is a better way to evaluate the list.
Some advice on your programming technique. You should use head matching and unification instead of explicit unification in the body of your predicate definitions, and if-else constructs. You should also avoid not tail-recursive recursion, unless your algorithm is inherently recursive (in-order tree traversal, for example). This will make the code easier to write, read, and understand. Right now, I don't even feel like debugging your code, but it looks like your Store2 would never be bound to an integer, and is always going to be an unbound variable, no matter what input your program has.
Now to your program. It is not clear what you are trying to achieve. If you only want to evaluate list of the form [Arithmetic_operator, Operand1, Operand2], it would be much easier to write:
arith_eval(Expression_list, Result) :-
Arithmetic_expr =.. Expression_list, % look up what =.. stands for!
Result is Arithmetic_expr.
I don't see the need for this overly complicated approach you are using.
If you want to be able to evaluate arbitrarily complex expressions, written in post-fix, with fixed operator arity (so you can say 2, 3, +, but not 2, 4, 1, +, for a sum of 7):
Read one element from your input
Push the element to the top of the stack
Try to reduce the stack:
pop operator and operands, if on top of the stack
evaluate
push result back on the top of the stack
When input is empty, your stack is your result
You could explicitly define the effect of different operators (here, only + and -) like this:
eval_stack([+,A,B|Tail],[Result|Tail]) :-
number(A), number(B),
!,
Result is B + A.
eval_stack([-,A,B|Tail],[Result|Tail]) :-
number(A), number(B),
!,
Result is B - A.
eval_stack(Stack,Stack).
Note how either an operator matches the top of your stack, and is applied when there are operands below it, pushing the result back on the stack, or the stack is left unchanged.
And you can push from your input to your stack:
evaluate([Next|Rest], Stack, Result) :-
eval_stack([Next|Stack],NewStack),
evaluate(Rest,NewStack,Result).
evaluate([],Result,Result). % end of input
So now you could call this with:
?- evaluate([2,3,+,3,6,-,+],[],Result).
Result = [2].
?- evaluate([2,3,4,-,-,5,+],[],Result).
Result = [8].
?- evaluate([2,3,4,-,-,5,+,1,3,2,-],[],Result).
Result = [1,1,8].
So these two predicates, evaluate(Input,Stack,Result), and eval_stack(Stack,NewStack) is all you would need for evaluating a valid post-fix arithmetic expressions with fixed-arity operators only.

Evaluating set expressions

I have a universe of elements organized into n non-disjoint sets. I have m expressions built using these sets, using union/intersection/difference operators. So given an element, I need to evaluate these m expressions, to find out which of the "derived" sets contain the element. I do not want to compute the "derived" set because it will be very time and space inefficient. Is there a way to say whether an element will lie in one of the derived sets just by looking at its expression? For e.g. if the expression is C = A U B and the element lies in set A, then i can say that it will lie in set C. Are there any C libraries to perform computations of this nature?
if im not mistake,
let e = the element
replace each set A, B with true if e is in the set, false if its not. Then, convert the set operators to their logical equivalents, and evaluate the expression as boolean. It should all map well to boolean operators, even xor and stuff.
for example, if e is in both A B, but not D
C = (A U B) xor D
it would be in C because
C = (true or true) xor false
-> (true) xor false
-> true
That could be pretty fast if you can quickly find if an element is in a set