I am new to ProLog and I am having some troubles understanding recursion over lists.
I am stuck on this exercise. Basically given the vocabulary I need to convert a list of Italian numbers to English numbers.
This is my KB.
tran(uno, one).
tran(due, two).
tran(tre, three).
tran(quattro, four).
tran(cinque, five).
tran(sei, six).
tran(sette, seven).
tran(otto, eight).
tran(nove, nine).
listran(L,[]).
listran(L,[H|T]) :- tran(H,E), listran([E|L],T).
This program should give the translated list (in reverse order). However, it only outputs true when I pass:
?- listran(X, [uno, due, tre]).
I've tried to trace it and seems that at the end removes?? all elements from my translated list. This is the trace output.
[trace] ?- listran(X,[uno,due,tre]).
Call: (8) listran(_5566, [uno, due, tre]) ? creep
Call: (9) tran(uno, _5820) ? creep
Exit: (9) tran(uno, one) ? creep
Call: (9) listran([one|_5566], [due, tre]) ? creep
Call: (10) tran(due, _5826) ? creep
Exit: (10) tran(due, two) ? creep
Call: (10) listran([two, one|_5566], [tre]) ? creep
Call: (11) tran(tre, _5832) ? creep
Exit: (11) tran(tre, three) ? creep
Call: (11) listran([three, two, one|_5566], []) ? creep
Exit: (11) listran([three, two, one|_5566], []) ? creep
Exit: (10) listran([two, one|_5566], [tre]) ? creep
Exit: (9) listran([one|_5566], [due, tre]) ? creep
Exit: (8) listran(_5566, [uno, due, tre]) ? creep
true.
Can someone help me understanding this little problem?
Thank you in advance.
The problem is in both clauses:
listran(L,[]).
listran(L,[H|T]) :- tran(H,E), listran([E|L],T).
here you state that: translate H and place it to head of L and continue, this holds for every L, you need explicitly state that the current head of L is E not add E:
listran([],[]).
listran([E|T1],[H|T]) :- tran(H,E), listran(T1,T).
Here you say the head of first list is E and continue with rest until base case where both lists are empty.
An interesting (and "prologish") way is to use DCG :
tran(uno) --> [one].
tran(due) --> [two].
tran(tre) --> [three].
tran(quattro) --> [four].
tran(cinque) --> [five].
tran(sei) --> [six].
tran(sette) --> [seven].
tran(otto) --> [eight].
tran(nove) --> [nine].
listran(In,Out) :-
phrase(trans(In), Out).
trans([]) --> [].
trans([H|T]) --> tran(H), trans(T).
Related
I'm trying to implement a recursive backtracking function using depth first search and I'm stuck in a point where I need to know my previous position in a matrix.
The idea is this: I have a matrix as a 2D Array and this is my function:
Mark the current point,if the point is what I'm looking for, I set the point in the matrix as part of the solution and all the previously marked points as part of the solution as well.
Else I call the function to a valid adjacent point.
The problem is the third case: if there are no valid adjacents points, then I need to mark the point as wrong and call the function to my previous location. To do that I think I need a stack that keeps track of my previous movement but I'm having an hard time figuring out how to do so in f#.
let rec solve (x,y) =
mark (x,y)
if (x,y) = pointimlookingfor then
for x in 0.. array width-1 do
for y in 0..array height-1 do
if Myarray.[x,y]=markedpoint then
Myarray.[x,y]<-partofsolution
else if (List.isEmpty(adjacentslist) then
Myarray.[x,y]<-wrong point
solve (the previous visited point)
else
for (adjacentpoint) in adjacentslist do
solve(adjacentpoint)
Any ideas?
In most functional languages, the default list type is an immutable linked-list, which you can use as a simple stack, because of its construction.
cons is push into stack, and head is pop from stack.
With that, we can write a simple stack module.
module Stack =
let empty = []
let push item stack = item::stack
let pop = function
| [] -> failwith "No items in stack"
| x::xs -> xs
let peek stack = stack |> List.tryHead
So,
Stack.empty |> Stack.push 1 |> Stack.push 2 |> Stack.pop |> Stack.pop = Stack.empty //true
In actual practice, instead of explicitly using functions like the above, the easiest way is to use pattern matching on some accumulator which you carry with you as you recurse/fold.
For an example, let's re-create a classic use-case for a stack - balancing parenthesis.
Every time you encounter an open brace, you push to stack, when you encounter a closing brace, you pop from the stack, and see if it matches the last one you pushed in. If it doesn't, it's unbalanced.
let rec isBalanced stack = function
| '(' | '{' | '[' as opened -> opened::stack //push into stack
| ')' | '}' | ']' as closed ->
match stack with
| opened::rest as all -> //pop from stack
match opened, closed with
| '(', ')'
| '{', '}'
| '[', ']' -> rest
| _ -> failwith "Mismatched braces"
| [] -> failwith "Closing before open"
| _ -> stack
"abc() { [ 1; 2; 3] }" |> Seq.fold (isBalanced) []
There are more concise ways to write this, but this illustrates how you can simulate a classical stack with immutable structures.
In your case, you could push an (x,y) tuple on to the stack, and let the algorithm backtrack by destructuring it: (x,y)::tail.
I have found written
"A message can ONLY be received within the same communicator from which it was sent".
However, if I look at this picture
https://imgur.com/a/hYz4dWd
and then analyze this code
Send and Receive operations between communicators in MPI
use mpi !instead of include 'mpif.h'
implicit none
integer :: tag,ierr,rank,numtasks,color,new_comm,inter1,inter2
integer :: sendbuf,recvbuf,stat(MPI_STATUS_SIZE)
integer :: irank
!
tag = 22
sendbuf = 222
!
call MPI_Init(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,numtasks,ierr)
!
if (rank < 2) then
color = 0
else
color = 1
end if
!
call MPI_COMM_SPLIT(MPI_COMM_WORLD,color,rank,new_comm,ierr)
!
if (color .eq. 0) then
call MPI_INTERCOMM_CREATE(new_comm,0,MPI_Comm_world,2,tag,inter1,ierr)
!
call MPI_COMM_RANK(inter1,irank,ierr)
if(irank==0)then
call mpi_send(sendbuf,1,MPI_INT,0,tag,inter1,ierr)
end if
!
else if(color .eq. 1) then
call MPI_INTERCOMM_CREATE(new_comm,0,MPI_COMM_WORLD,0,tag,inter2,ierr)
call MPI_COMM_RANK(inter2,irank,ierr)
if(irank==0)then
call mpi_recv(recvbuf,1,MPI_INT,0,tag,inter2,stat,ierr)
if(ierr/=MPI_SUCCESS)print*,'Error in rec '
print*,'rec buff = ', recvbuf
end if
end if
!
call MPI_finalize(ierr)
end program h
to me it seems that I am communicating between two different communicators: inter1 and inter2. Turning to the picture attached, I am communicating from comm1 towards comm2.
The picture is unrelated to the sample code.
Looking at the code, one rank MPI_Send(..., inter1, ...) and an other MPI_Recv(..., inter2, ...).
What matters here is how inter1 and inter2 were created, and they both come from all the ranks invoking MPI_Intercomm_create(), so even if you use different variable names, they indeed refer to the same (and unique) inter-communicator.
Here is a more intuitive way the program could have been written
use mpi !instead of include 'mpif.h'
implicit none
integer :: tag,ierr,rank,numtasks,color,new_comm,inter,remote_leader
integer :: sendbuf,recvbuf,stat(MPI_STATUS_SIZE)
integer :: irank
!
tag = 22
sendbuf = 222
!
call MPI_Init(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,numtasks,ierr)
!
if (rank < 2) then
color = 0
remote_leader=2
else
color = 1
remote_leader=0
end if
!
call MPI_COMM_SPLIT(MPI_COMM_WORLD,color,rank,new_comm,ierr)
!
call MPI_INTERCOMM_CREATE(new_comm,0,MPI_Comm_world,remote_leader,tag,inter,ierr)
call MPI_COMM_RANK(inter,irank,ierr)
if (irank.eq.0) then
if(color.eq.0) then
call mpi_send(sendbuf,1,MPI_INT,0,tag,inter,ierr)
else if(color.eq.1) then
call mpi_recv(recvbuf,1,MPI_INT,0,tag,inter,stat,ierr)
if(ierr/=MPI_SUCCESS)print*,'Error in rec '
print*,'rec buff = ', recvbuf
end if
end if
!
call MPI_finalize(ierr)
end program
I wrote the following function that checks the validity of bracketed expressions:
let matched str =
let rec matched' stack = function
| "" -> isEmpty stack
| str ->
match first str with
| '(' | '[' | '{' as p -> matched' (push p stack) (rest str)
| ')' -> matchClosing '(' stack str
| ']' -> matchClosing '[' stack str
| '}' -> matchClosing '{' stack str
| _ -> matched' stack (rest str)
and matchClosing expected stack s =
match peek stack with
| Some c when c = expected -> matched' (pop stack) (rest s)
| _ -> false
matched' [] str
If we substitute the implementation of matchClosing into matched', we get a tail recursive function. Can the F# compiler recognize this and optimize away the recursive calls?
AFAICT your example isn't complete which makes it harder to check. I complemented it somewhat and was able to compile it.
Using ILSpy one sees that the mutual recursion is still in place:
// F#: | ')' -> matchClosing '(' stack str
case ')':
return Program.matchClosing#39('(', stack, str);
// F#: | matched' t (tail s)
return Program.matched'#28(t, s.Tail);
So while it should be technically possible to unpack two mutually tail recursive function into a loop it's not done.
When checking the IL code we see that the the calls are tagged with .tail
// F#: | matchClosing '(' stack str
IL_0083: tail. // Here
IL_0085: call bool Program::matchClosing#39(char, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<char>, valuetype Program/SubString)
// F#: | matched' t (tail s)
IL_002a: tail. // Here
IL_002c: call bool Program::'matched\'#28'(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<char>, valuetype Program/SubString)
The .NET Jitter is in release mode kind enough to consider .tail flag
// As you can see when debugging the code in WinDbg
02410bdf e8fbd3176b call clr!JIT_TailCall (6d58dfdf)
We also see when we debug in WinDbg that the stack don't grow. Unfortunately when looking at clr!JIT_TailCall it does a fair amount of work meaning while it doesn't consume stack it consumes clock cycles instead like noted here: How to eliminate time spent in JIT_TailCall for functions that are genuinely non-recursive
However in Debug mode (and at least older versions of Mono) .tail flag is ignored
// As you can see when debugging the code in WinDbg (this is a normal call)
02f619c1 e8c2f4ffff call 02f60e88
We also see when we debug in WinDbg that the stack grow.
So the answer to your question should be:
No, the F# compiler isn't able to transform the mutually tail recursive calls into a loop.
However, the F# compiler tags the calls with a .tail attribute
The Release mode JIT:er kindly considers the .tail attributes and generates tail calls that don't grow the stack (but are ineffecient)
In Debug mode (and possibly mono) .tail attributes are ignored and no tail calls are generated by the JIT:er and the stack will grow.
I am very new to prolog and am having some issues understanding some basic arithmetic. I want to create a functor that will recursively multiply. IE: 3*4 = 3+3+3+3 = 12.
I put it through SWIPL's trace command and it fails when decrementing Count.
Here is the code I have so far but it does not work.
multn(_,0,0).
multn(_, Count ,Return) :- Count is Count-1,
Return is 0,
multn(_,Count,Return),
Return is Return + _.
EDIT: made some new changes based on what you said about the functionality of "is".
multn(_, Count ,Return) :- Count1 is (Count-1),
multn(_,Count1,Return1),
Return is (Return1 + _).
Now it is making it all the way down the recursion chain to the base case and when it starts it way back up it fails out trying to todo Return is (Return1+ _). It seems to be changing the _ variable. here it my trace:
[trace] ?- multn(3,2,X).
Call: (6) multn(3, 2, _G388) ? creep
^ Call: (7) _L142 is 2+ -1 ? creep
^ Exit: (7) 1 is 2+ -1 ? creep
Call: (7) multn(_L160, 1, _L143) ? creep
^ Call: (8) _L163 is 1+ -1 ? creep
^ Exit: (8) 0 is 1+ -1 ? creep
Call: (8) multn(_L181, 0, _L164) ? creep
Exit: (8) multn(_L181, 0, 0) ? creep
^ Call: (8) _L143 is 0+_G461 ? creep
ERROR: is/2: Arguments are not sufficiently instantiated
^ Exception: (8) _L143 is 0+_G461 ? creep
Exception: (7) multn(_L160, 1, _L143) ? creep
Exception: (6) multn(3, 2, _G388) ? creep
Last EDIT: Finally figured it out, using _ was causing the weird change in value. Thanks for your help.
It looks like your don't understand how Prolog works.
The key thing to understand is that both Count in Count is Count-1 are the same, they must have the same value. It's like variables in algebra - all Xs in an equation means the same value. So Count is Count-1 will always fail.
Similar problems with Return variable.
In Prolog you have to introduce new variables to do what you intended, like NewCount is Count-1.
I am working on Euler 8. After a bit of reading i decided that use of the map function would solve a problem for me. Throwing a simple test program together to make sure I understood the concepts came up short.
From within the shell.
1> List = {3, 1, 4}.
{3,1,4}
2> io:format("oh my ~w ~n", [List]).
oh my {3,1,4}
ok
3> lists:map(fun (Z) -> Z * Z end , List).
** exception error: no function clause matching
lists:map(#Fun<erl_eval.6.80247286>,{3,1,4})
I see the fun, and the list in the message.
What concept am I missing here?
your List is actually a tuple. {} is for tuples, [] is for lists.
your example should be:
1> List = [3,1,4].
[3,1,4]
2> lists:map(fun(Z) -> Z*Z end, List).
[9,1,16]
You are trying to apply lists:map function on tuple. Initiate List = [3,1,4] not as List = {3,1,4} and apply the same function, you will get desired output.