Recursive call in OCaml [closed] - recursion

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to implement a recursive call in OCaml, using the next code :
| Add (x,y) ->
begin
match x, y with
| x, Bra y -> Bra (Implies(x, y))
| x, Add (a, b) -> Add(x, Add(a, b))
| x, y -> Implies(x, y)
end
When testing it with 2 cases, I found that in the case 2 the program enters in an infinity loop.
+(p,[] z)
it returns [](p => z)
+(p,+(q,[] z))
it should return [](p => (q => z)) , but instead of that goes inside the never ending loop.
I can see that the problem with case 2, is because I am calling Add inside another Add operator. But I understand here that the "exit" of the loop should be given by the first line of the match clause, however it is not working.
If you have any advice I would be grateful.
Just to clarify, I am using the next syntax for the operators
Add + , Bra [], Implies =>

In this code extract, some value (let's say v) matches Add (x,y). In particular, there is a case where y matches Add (a, b). That means that v is equal to this value:
Add (x, Add (a, b))
But, notice that the return value of your function in this case is also:
Add (x, Add (a, b))
There, v is returned unchanged.
If your code loops until there is no more Add (I don't know, because the code is incomplete, please post a Minimal, Reproducible Example), then this branch of your code produces a fixpoint, which may explain the infinite loop.

Related

Why can't we replace the def of "many" with the code using <~> in Opal? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have an question about https://github.com/pyrocat101/opal/blob/master/opal.ml.
At line 105, I replaced the definition of many with let rec many x = option [] (x <~> many x);;. Then, I got the following error message:
Stack overflow during evaluation (looping recursion?).
However, these two codes seem to be same. Why?
I used OCaml version 4.12.0.
OCaml is an eager language. Thus in
let rec many x = option [] (x <~> many x)
the inner expression many x is fully evaluated as soon as the argument x is provided. Consequently, evaluating many x requires to evaluate many x and the function loops.
The smallest fix is to avoid hiding the input argument of many:
let rec many x input = option [] (x <~> many x) input
(In other words, point-free style is not consequence free in an eager and mutable language.)
Since the inner many x is a closure here, its execution will be suspended breaking the loop.
Similarly, the inlined version
let rec many x = option [] (x >>= fun r -> many x >>= fun rs -> return (r :: rs))
achieve the same result by moving the inner expression many x in an anonymous function fun r -> ....

Give regular expressions of Σ = {a, b} [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
The question ask me to give regular expressions on Σ = {a, b}, which exactly define the following languages.
These are;
(a) L1 which has exactly one b but any number of as.
(b) L2 which has an even number of as and an even number of bs.
I am struggling on what would the answers be. I would appreciate if you could help me out. Thank you
(a) We need exactly one b, which can occur anywhere in our strings; and we can have any number of the other symbols, the only one of which is a; so, our regular expression is (a*)b(a*) (note: the parentheses are added for clarity only and can be omitted).
(b) A little more complicated. See below.
(c) We can write regular expressions for each case and then union them to get one regular expression; the cases are just like (a) above: (a*)b(a*)b(a*) + (b*)a(b*)a(b*)
(d) Again, we can do each case separately and union the answers: (a*)(b*) + (b*)(a*)
(e) A little more complicated, though easier than (b). See below.
For (b) and (e) I recommend writing down a finite automaton, then a regular grammar, then solving the set of implied equations to find the regular expression. I will do (e) as an example and leave (b) as an exercise.
A finite automaton for (e) is this:
+---a-----+
| |
V |
(q0)--a-->(q1)
| ^ | ^
+-b| +-b|
The regular grammar is this:
(q0) -> e | a(q1) | b(q0)
(q1) -> a(q0) | b(q1)
The set of implied equations:
(q0) = e + a(q1) + b(q0)
(q1) = a(q0) + b(q1)
We can simplify each line using the rule q = rq + s => q = r*s:
(q0) = (b*)[a(q1) + e] = (b*)a(q1) + (b*)
(q1) = (b*)a(q0)
Now we substitute and simplify:
(q0) = (b*)a(b*)a(q0) + (b*)
= [(b*)a(b*)a]*(b*)
There you have your answer: a regular expression for (e) is [(b*)a(b*)a]*(b*). Now that we have the answer to look at it sort of makes sense: the part in square brackets contains exactly two a's, starring it gives any even number, and then finishing with b* means we don't need an a on the end (though we can have one if we want to).
For (b): either do what we did for (e) (note that you will have a four-state DFA, four nonterminals and four equations, but you can solve the system the same way we just did), or use the other expressions we've made and any insights you've gleaned to see if there's a simpler way to combine things to get the required expression.

Avoiding infinite recursion but still using unbound parameter passing only

I have the following working program: (It can be tested on this site: http://swish.swi-prolog.org, I've removed the direct link to a saved program, because I noticed that anybody can edit it.)
It searches for a path between two points in an undirected graph. The important part is that the result is returned in the scope of the "main" predicate. (In the Track variable)
edge(a, b).
edge(b, c).
edge(d, b).
edge(d, e).
edge(v, w).
connected(Y, X) :-
(
edge(X, Y);
edge(Y, X)
).
path(X, X, _, []) :-
connected(X, _).
path(X, Y, _, [X, Y]) :-
connected(Y, X).
path(X, Z, Visited, [X|Track]) :-
connected(X, Y),
not(member(X, Visited)),
path(Y, Z, [X|Visited], Track).
main(X, Y) :-
path(X, Y, [], Track),
print(Track),
!.
Results:
?- main(a, e).
[a, b, d, e]
true
?- main(c, c).
[]
true
?- main(b, w).
false
My questions:
The list of visited nodes is passed down to the predicates in 2 different ways. In the bound Visited variable and in the unbound Track variable. What are the names of these 2 different forms of parameter passing?
Normally I only wanted to use the unbound parameter passing (Track variable), to have the results in the scope of the main predicate. But I had to add the Visited variable too, because the member checking didn't work on the Track variable (I don't know why). Is it possible to make it work with only passing the Track in an unbound way? (without the Visited variable)
Many thanks!
The short answer: no, you cannot avoid the extra argument without making everything much messier. This is because this particular algorithm for finding a path needs to keep a state; basically, your extra argument is your state.
There might be other ways to keep a state, like using a global, mutable variable, or dynamically changing the Prolog data base, but both are more difficult to get right and will involve more code.
This extra argument is often called an accumulator, because it accumulates something as you go down the proof tree. The simplest example would be traversing a list:
foo([]).
foo([X|Xs]) :-
foo(Xs).
This is fine, unless you need to know what elements you have already seen before getting here:
bar(List) :-
bar_(List, []).
bar_([], _).
bar_([X|Xs], Acc) :-
/* Acc is a list of all elements so far */
bar_(Xs, [X|Acc]).
This is about the same as what you are doing in your code. And if you look at this in particular:
path(X, Z, Visited, /* here */[X|Track]) :-
connected(X, Y),
not(member(X, Visited)),
path(Y, Z, [X|Visited], /* and here */Track).
The last argument of path/4 has one element more at a depth of one less in the proof tree! And, of course, the third argument is one longer (it grows as you go down the proof tree).
For example, you can reverse a list by adding another argument to the silly bar predicate above:
list_reverse(L, R) :-
list_reverse_(L, [], R).
list_reverse_([], R, R).
list_reverse_([X|Xs], R0, R) :-
list_reverse_(Xs, [X|R0], R).
I am not aware of any special name for the last argument, the one that is free at the beginning and holds the solution at the end. In some cases it could be an output argument, because it is meant to capture the output, after transforming the input somehow. There are many cases where it is better to avoid thinking about arguments as strictly input or output arguments. For example, length/2:
?- length([a,b], N).
N = 2.
?- length(L, 3).
L = [_2092, _2098, _2104].
?- length(L, N).
L = [],
N = 0 ;
L = [_2122],
N = 1 ;
L = [_2122, _2128],
N = 2 . % and so on
Note: there are quite a few minor issues with your code that are not critical, and giving that much advice is not a good idea on Stackoverflow. If you want you could submit this as a question on Code Review.
Edit: you should definitely study this question.
I also provided a somewhat simpler solution here. Note the use of term_expansion/2 for making directed edges from undirected edges at compile time. More important: you don't need the main, just call the predicate you want from the top level. When you drop the cut, you will get all possible solutions when one or both of your From and To arguments are free variables.

Why do some functional languages not use parenthesis for function arguments? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've been trying to a adopt a functional language into my programing. I use C# and rely heavily on LINQ and other functional constructs. Currently I'm focusing on Elm.
One thing that continues to bother me is the lack of parenthesis in functions. Math expressions use them:
f(z) = ln(z) + 1
Yet in many functional languages this is written as:
f z = ln z + 1
It this just a style thing or is there something deeper going here?
Functional languages take root in lambda calculus, which do not use parentheses for functional application.
It is a syntactical thing sure, but the way that functions are applied it makes sense to leave parentheses out since a function with two arguments first applies the left most argument to the function and output a function that is used by the second argument. For example the function you are used to:
add(x,y) { return x + y }
in functional terms is
add x y
add :: Int->Int->Int
where the intermediate step after applying x returns another function
add 4 -- returns a function that will return 4 + y, when y is applied
add 4 :: Int->Int
To a certain degree this helps avoid confusion with the programming languages you are used to where add(4) would throw an error. It reads more like math with associativity, ((add x) y).
One of the reasons to avoid parenthesis in function application is currying.
If you code f x y (like you should in Ocaml) then f x is simply a curryfication. If you don't have such a notation, you need an explicit lambda (or some anonymous function notation), like in Scheme (lambda (y) (f x y))
On the other hand, languages with currying often implicitly interpret f x y as (f x) y and then their implementation need to optimize that to avoid creating useless temporary closures.
I have mixed feelings w.r.t. currying. It is perhaps not often useful (but you'll need it sometimes), and a short anonymous function notation is perhaps enough
Alot of the notation we see is influenced my mathematics, and I've seen atleast two types of function notation within maths to show domain to codomain mapping.
f(x) = x + 1 and x -> x + 1
So I guess maybe the languages without parenthesis derive from the later maybe

Using fold in SML

I'm trying to learn smlnj at the moment and am having trouble with a fold function.
What I'm trying to do is write a function, select, that uses the folding pattern and takes in a function and a list. It will take the head of the list into the function to determine whether it will add that element to the list. Here is an example of what I mean.
select (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
So, here is what I have so far...
fun select f l = foldl (fn (x,y) => if (f(x)) then x else 0) 0 l;
This obviously doesn't work correctly. It simply returns 10. I'm sure I need to use op:: somehow to get this to work, but I can't figure it out. My thought is that it should look something like this...
fun select f l = foldl (fn (x,y) => if (f(x)) then op:: else []) [] l;
But this does not work. Any help would be appreciated. Thanks!
You're close. The only problems are the if/else cases in the function you're passing to fold.
Remember, in your fn (x,y), x is the list element you're considering, and y is the result of folding the rest of the list. If f(x) fails, then you want to exclude x from the result, so you just pass y along. If f(x) succeeds, you want to include x in your result, so you return y#[x].
Note that it's best to avoid using the append operator (y#[x]) where you can, as it's a linear-time operation, while prepending (x::y) is constant. Of course, substituting one for the other in this case will construct your list backwards. You can get around this by folding backwards as well, i.e. using foldr instead of foldl.
What you're implementing already exists. It's called filter.
- List.filter (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
Your attempt in your second code sample is pretty close. There are several issues I might point out:
op:: is an operator, which is a function. You probably don't want to return a function. Instead, you probably want to use the operator to create a list from a head element and the rest of the list, like this: x :: y
In the else case, you are currently returning an empty list, and throwing away whatever was accumulated in y. You probably don't want to do that.
Think about whether left-fold or right-fold would be most suitable for your output

Resources