I am trying to create a tail recursive drop/3 in prolog. The way tail recursion was taught to us (poorly) doesn't even begin to show me how I need to even tackle this issue.
This is the only thing I have which does not even work and which isn't even tail recursive as far as I am aware. I am at the end of my mental rope, so any help would be appreciated.
drop(N, [], []).
drop(N, [A,As], Bs) :-
integer(N),
N > 0,
N1 is N - 1,
Bs is As,
drop(N1, As, Bs).
You problems are:
[A,As] is a 2-element list (e.g, [ alpha, bravo ]) rather than breaking the list into its head and tail. [ H | T ] when applied to list [a,b,c] yields H being a and T being [b,c].
is/2 does arithmetic, so Bs is As doesn't work. . . and if it did, you are unifying with the result: a prolog variable, once unified is no longer variable, and so cannot be reassigned.
So, assuming that you want to implement this drop/3, try this:
drop( _ , [] , [] ) . % allows `drop(3, [a,b], R)` to succeed
drop( 0 , R , R ) . % dropping the first 0 element from a list returns the same list
drop( N , [_|T] , R ) :- % otherwise . . .
integer(N) , % - given that N is an integer, and
N > 0 , % - given that N is positive, then
N1 is N-1 , % - we decrement N, and
drop( N1, T , R ) % - recurse down, discarding the head (1st element) of the list
. % Easy!
Note that this will fail if you try to remove 3 elements from a 2-element list. It is a simple change to allow that case to succeed.
What makes this tail recursive is that the only state that matters is whats passed between the recursive calls. That means that the stack frame can be reused. And since no new frame as pushed onto the call stack, that essentially turns the recursive function call into iteration.
Related
I'm supposed to write a predicate that does some math stuff. But I don't know how to pass numbers or return numbers.
Maybe you can give me an example?
Let's say a predicate divide/2 that takes two numbers a and b and returns a/b.
Yes, you pass numbers in in some arguments, and you get the result back in some other argument(s) (usually last). For example
divide( N, D, R) :-
R is N / D.
Trying:
112 ?- divide(100,5,X).
X = 20.
113 ?- divide(100,7,X).
X = 14.285714285714286.
Now, this predicate is divide/3, because it has three arguments: two for inputs and one for the output "information flow".
This is a simplified, restricted version of what a Prolog predicate can do. Which is, to not be that uni-directional.
I guess "return" is a vague term. Expression languages have expressions e-value-ated so a function's last expression's value becomes that function's "return" value; Prolog does not do that. But command-oriented languages return values by putting them into some special register. That's not much different conceptually from Prolog putting some value into some logvar.
Of course unification is more complex, and more versatile. But still, functions are relations too. Predicates "return" values by successfully unifying their arguments with them, or fail to do so, as shown in the other answer.
Prolog is all about unifying variables. Predicates don't return values, they just succeed or fail.
Typically when a predicate is expected to produce values based on some of the arguments then the left-most arguments are inputs and the right-most are the outputs. However, many predicates work with allowing any argument to be an input and any to be a output.
Here's an example for multiply showing how it is used to perform divide.
multiply(X,Y,Z) :- number(X),number(Y),Z is X * Y.
multiply(X,Y,Z) :- number(X),number(Z),X \= 0,Y is Z / X.
multiply(X,Y,Z) :- number(Y),number(Z),Y \= 0,X is Z / Y.
Now I can query it like this:
?- multiply(5,9,X).
X = 45 .
But I can easily do divide:
?- multiply(5,X,9).
X = 1.8 .
It even fails if I try to do a division by 0:
?- multiply(X,0,9).
false.
Here's another approach. So let's say you have a list [22,24,34,66] and you want to divide each answer by the number 2. First we have the base predicate where if the list is empty and the number is zero so cut. Cut means to come out of the program or just stop don't go to the further predicates. The next predicate checks each Head of the list and divides it by the number A, meaning (2). And then we simply print the Answer. In order for it to go through each element of the list we send back the Tail [24,34,66] to redo the steps. So for the next step 24 becomes the Head and the remaining digits [34,66] become the Tail.
divideList([],0,0):-!.
divideList([H|T],A,Answer):-
Answer is H//A,
writeln(Answer),
divideList(T,A,_).
?- divideList([22,24,34,66],2,L).
OUTPUT:
11
12
17
33
Another simpler approach:
divideList([],_,[]).
divideList([H|T],A,[H1|L]):-
H1 is H//A,!,
divideList(T,A,L).
?-divideList([22,4,56,38],2,Answer).
Answer = [11, 2, 28, 19]
I see this code in the example of Elixir:
defmodule Recursion do
def print_multiple_times(msg, n) when n <= 1 do
IO.puts msg
end
def print_multiple_times(msg, n) do
IO.puts msg
print_multiple_times(msg, n - 1)
end
end
Recursion.print_multiple_times("Hello!", 3)
I see here the same function defined twice with different arguments, and I want to understand this technique.
Can I look at them as at overloaded functions?
Is it a single function with different behavior or are these two different functions, like print_only_once and print_multiple_times?
Are these functions linked anyhow or not?
Usually in functional languages a function is defined by clauses. For example, one way to implement Fibonacci in an imperative language would be the following code (not the best implementation):
def fibonacci(n):
if n < 0:
return None
if n == 0 or n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
To define the function in Elixir you would do the following:
defmodule Test do
def fibonacci(0), do: 1
def fibonacci(1), do: 1
def fibonacci(n) when n > 1 do
fibonacci(n-1) + fibonacci(n - 2)
end
def fibonacci(_), do: nil
end
Test.fibonacci/1 is only one function. A function with four clauses and arity of 1.
The first clause matches only when the number is 0.
The second clause matches only when the number is 1.
The third clause matches with any number greater than 1.
The last clause matches anything (_ is used when the value of the variable is not going to be used inside the clause or is not relevant for the match).
The clauses are evaluated in the order they are declared, so for Test.fibonacci(2) will fail in the first 2 clauses and match the third one because 2 > 1.
Think of clauses as a more powerful if statement. The code looks cleaner this way. And is very useful for recursion. For example, a map implementation (the language already provide one in Enum.map/2):
defmodule Test do
def map([], _), do: []
def map([x | xs], f) when is_function(f) do
[f.(x) | map(xs, f)]
end
end
First clause matches an empty list. No need to apply a function.
Second clause matches a list where the first element (head) is x and the rest of the list (tail) is xs and f is a function. It applies the function to the first element and recursively calls map with the rest of the list.
Calling Test.map([1,2,3], fn x -> x * 2 end) will give you the following output [2, 4, 6]
So, a function in Elixir is defined with one or more clauses where every clause have the same arity as the rest.
I hope this answers your question.
In the example you posted both definitions of the function have the same number of arguments: 2, this "when" thing is a guard, but you can also have definitions with many arguments. First, guards -- they are uses to express what cannot be written as a mere matching, like the second line of the following:
def fac(0), do: 1
def fac(n), when n<0 do: "no factorial for negative numbers!"
def fac(n), do: n*fac(n-1)
-- since it's not possible to express being negative number by just equality/matching.
Btw this fac is a single definition, only with three cases. Notice the coolness of using constant "0" in the position of argument :)
You can think of this as it would be nicer way to write:
def fac(n) do
if n==0, do: 1, else: if n<0, do: "no factorial!", else: n*fac(n-1)
end
or a switch case (which even looks pretty close to the above):
def fa(n) do
case n do
0 -> 1
n when n>0 -> n*fa(n-1)
_ -> "no no no"
end
end
only "looks more fancy". Actually it turns out certain definitions (e.g. parsers, small interpreters) look much better in the former than latter style. Nb guard expressions are very limited (I think you can't use your own function in guard).
Now the real thing, varying number of arguments -- check this out!
def mutant(a), do: a*a
def mutant(a,b), do: a*b
def mutant(a,b,c), do: mutant(a,b)+mutant(c)
e.g.
iex(1)> Lol.mutant(2)
4
iex(2)> Lol.mutant(2,3)
6
iex(3)> Lol.mutant(2,3,4)
22
It works a bit similar like (lambda arg ...) in scheme -- think of mutant as taking all its arguments as a list and matching over it. But this time, elixir treats mutant as 3 functions, mutant/1, mutant/2, and mutant/3 and will refer to them as such.
So, to answer your question: these are not like overloaded functions, but rather scattered/fragmented definitions. You see similar ones in functional languages like miranda, haskell or sml.
I know this algorithm is for finding the majority element of any array if it has any. Can any one please explain the recursion calls?
if length(A) = 0 then
return null
end if
if length(A) = 1 then
return 1
end if
// "Command 7"
Call FIND-MAJORITY recursively on the first half of A, and let i be the result.
// "Command 8"
Call FIND-MAJORITY recursively on the second half of A, and let j be the result.
if i > 0 then
compare i to all objects in A(including itself);
let k be the number of times that equality holds;
if k > length(A)/2 then
return i.
end if
end if
if j > 0 then
compare j to all objects in A(including itself);
let k be the number of times that equality holds;
if k > length(A)/2 then
return j
end if
end if
return null
Is command 7 is executed until it get an single value ... and then command 8? I cannot understand these recursions. Please explain with example, thanks.
It depends what are inputs of this function.
If the array A is an input then we only search in the diminished array else if the array A is defined as global then you always search the whole array.
For example take the array A is 1,2,1,3,1,8,7,1
If the array is given as input to the function :
According to recursion we get A is 1,2,1,3 -> A is 1,2 -> A is 1
This returns i := 1.
Then A is 2, this returns j:=1.
Then we compare i to all elements of A i.e 1,2.
Then we compare j to all elements of A i.e. 1,2.
We return null from this recursive call.
After this we proceed to upper recursion i.e. 1,2,1,3 and up to the first call.
If the array is global:
According to recursion we get A is 1,2,1,3 -> A is 1,2 -> A is 1
This returns i := 1.
Then A is 2, this returns j:=1.
Then we compare i to all elements of A i.e. 1,2,1,3,1,8,7,1
we return according to the conditions.
**Remember even in this case we return all recursive calls and check the whole array for every recursive call which is not what you probably want.
This is supposed to calculate the sum of two lists. The lists can be of different size.
sum([],[],[]).
sum(A,[],A).
sum([],B,B).
sum([A|Int1],[B|Int2],[C|Int3]) :-
(
C =:= A + B
;
((C =:= A), B = [])
;
((C =:= B), A = [])
),
sum(Int1,Int2,Int3).
It seems to work correctly, except when trying to find the sum of two lists. Then it gives the following error:
ERROR: =:=/2: Arguments are not sufficiently instantiated
I don't see why. There's a recursive and a basis step, what exactly is not yet instantiated and how do I fix it?
[1] While your disjunctions in the last clause are -- to some extent -- conceptually correct, Prolog considers these disjunctions in sequence. So it first considers C =:= A + B. But either A or B can be the empty list! This is what causes the error you reported, since the empty list is not allowed to occur in a numeric operation.
[2] You need to use C is A + b (assignment) i.o. C =:= A + B (numeric equivalence).
[3] If you say [A|Int1] and then A = [], then this means that [A|Int1] is not (only) a list of integers (as you claim it is) but (also) a list of lists! You probably intend to check whether the first or the second list is empty, not whether either contains the empty list.
Staying close to your original program, I would suggest to reorder and change things in the following way:
sumOf([], [], []):- !.
sumOf([], [B|Bs], [C|Cs]):- !,
C is B,
sumOf([], Bs, Cs).
sumOf([A|As], [], [C|Cs]):- !,
C is A,
sumOf(As, [], Cs).
sumOf([A|As], [B|Bs], [C|Cs]):-
C is A + B,
sumOf(As, Bs, Cs).
For example:
?- sumOf([1,2,3], [1,-90], X).
X = [2, -88, 3]
Notice my use of the cut (symbol !) in the above. This makes sure that the same answer is not given multiple times or -- more technically -- that no choicepoints are kept (and is called determinism).
You should read a tutorial or a book. Anyway, this is how you add two things to each other:
Result is A + B
This is how you could add all elements of one list:
sum([], 0). % because the sum of nothing is zero
sum([X|Xs], Sum) :-
sum(Xs, Sum0),
Sum is X + Sum0.
And this is how you could add the sums of a list of lists:
sums([], 0).
sums([L|Ls], Sums) :-
sums(Ls, Sums0),
sum(L, S),
Sums is Sums0 + S.
I'm a newcomer to J and I've been trying to create a Fibonacci function as an exercise (always the second function I create when learning a language). I just can't figure out what exactly is wrong in my way of doing it. I have tried to define it as tacit, but it gets hung if argument is greater than one.
fib =: [ ` (($: (]-1)) + ($: (]-2))) #. (>&1)
I've also attempted to create it explicitly, and that worked fine.
fib =: 3 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
I tried to create a tacit out of that by replacing 3 with 13, but it threw an error.
fib =: 13 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
|spelling error
| if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.
| ^
| fib=: 13 :'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
So, I'm asking for someone to explain what exactly I am doing wrong here.
Here's an alternative that I think is both clearer and more concise:
fibn =: (-&2 +&$: -&1)^:(1&<) M."0
Compare with a more canonical (pseudocode) definition:
fib(n) = fib(n-1) + fib(n-2) if n > 2 else n
First, instead of using [ ` with #. (>&1), which uses a gerund, it's better to use ^:(1&<). For f(n) if cond(n) else n, using the ^: conjunction is more idiomatic; ^:0 means "do nothing" and ^:1 means "do once," so the intent is clear. #. is better suited to nontrivial behavior.
Second, using the & bond/compose conjunction simplifies the train significantly. Repeated uses of [: and ] are rather confusing and opaque. Refactoring using & puts together related operations: first, split n into two, namely n-2 and n-1, and second, add together the fibn of those two numbers.
And, lastly, "0 for list handling and M. for memoizing. M. is rather important from a performance perspective, as a straightforward implementation of the canonical definition will call fib(2) excessively. You can have your cake (a simple definition) and eat it too (good performance) with the built-in memoization adverb.
Source for this particular definition: f0b on this page.
Okay, I found it. I ran only the recursive block through tacit generator and got this block.
13 : '(f y-1) + (f y-2)'
([: f 1 -~ ]) + [: f 2 -~ ]
Then I inserted that to the original piece, getting this.
fib =: [ ` (([: $: 1 -~ ]) + [: $: 2 -~ ]) #. (>&1)
And that works like a charm. I also inserted " 0 to the end to make it accept lists.