prolog predicate implementation handles cycles properly avoiding infinite loops - recursion

A single query to complete my program should check if there is a direct route between two given
cities. Alternatively, it can list all the connected cities for a given city. See the following:
flight(city1,city2).
flight(city2,city1).
flight(city2,city3).
flight(city3,city2).
My predicates:
route(X,Y):-
flight(X,Y).
route(X,Y) :-
flight(X,Z),
route(Z,Y).
My result :
?- route(city1,X).
X = city2 ;
X = city1 ;
X = city3 ;
X = city2 ;
X = city1 ;
X = city3 ;
X = city2 ;
X = city1 ;
X = .......
But i have infinitie recursion , and it can not stop. What can i solve this problem ?

Related

Declare multiple variable bindings in one line in SML

Is it possible to declare multiple variable bindings in one line in SML? For example, I have the following:
let
val m1 = [1]
val m2 = [2]
val m3 = [3]
in
{...}
end
I would like to condense this down to something like
let
val m1 = [1], m2 = [2], m3 = [3]
in
{...}
end
This syntax doesn't work, but is there a way to declare multiple variable bindings in one line like this?
Here are two ways:
- let val x = 1 val y = 5 in x + y end;
val it = 6 : int
- let val x = 1 and y = 5 in x + y end;
val it = 6 : int
I personally find the slight abuse of and more readable.
However, I think the "destructuring bind" method is more common than either of these, since it's also more generally useful.
- let val (x, y) = (1,5) in x + y end;
val it = 6 : int
- fun f x = (x, x + 2, x + 3);
val f = fn : int -> int * int * int
- let val (x, y, z) = f 3 in x + z end;
val it = 9 : int
You could create a tuple and immediately destructure it.
let
val (m1, m2, m3) = ([1], [2], [3])
in
...
end

Count number of vowels in a string using Prolog

I am new in prolog, so i have to explain these code to my class teacher.
can someone please explain this code. Thanks
vowel(X):- member(X,[a,e,i,o,u]).
nr_vowel([],0).
nr_vowel([X|T],N):- vowel(X),nr_vowel(T,N1), N is N1+1,!.
nr_vowel([X|T],N):- nr_vowel(T,N).
output:
1 ?- nr_vowel([a,t,i,k],X).
X = 2.
https://i.stack.imgur.com/dGfU5.jpg
An explanation is indeed highly appropriate.
For example, let us ask the simplest question:
Which solutions are there at all?
Try out out, by posting the most general query where all arguments are fresh variables:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1.
Hm! That's probably not what you wanted to describe!
So I change your code to:
nr_vowel([], 0).
nr_vowel([X|T], N):-
vowel(X),
nr_vowel(T,N1),
N #= N1+1.
nr_vowel([X|T], N):-
nr_vowel(T,N).
Then we get:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [a, a],
N = 2 ;
Ls = [a, a, a],
N = 3 ;
etc.
Looks better!
How about fair enumeration? Let's see:
?- length(Ls, _), nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [e],
N = 1 ;
Ls = [i],
N = 1 ;
Ls = [o],
N = 1 ;
Ls = [u],
N = 1 ;
Ls = [_2006],
N = 0 ;
Ls = [a, a],
N = 2 ;
Ls = [a, e],
N = 2 .
The first few answers all look promising, but what about Ls = [_2006], N = 0?
This is clearly too general!
You must make your program more specific to avoid this overly general answer.
Here is the problem in a nutshell:
?- nr_vowel([X], N), X = a.
X = a,
N = 1 ;
X = a,
N = 0.
Whaaat? a is a vowel, so why is N = 0??
Here is it in a smaller nutshell:
?- nr_vowel([a], 0).
true.
Whaaaaat??
I leave adding suitable constraints to the predicate as an exercise for you.
The code is simplistic in itself, all it does is count the number of vowels in a list (Guess that's quite evident to you).
Let's take your input as an example, the list is [a,t,i,k]
When you call nr_vowel([a,t,i,k],Z), prolog searches for and unifies the query with the second nr_vowel clause, this is because it is the first clause with a non-empty list input.
Now, vowel(a) returns true, so prolog moves on to the next predicate, which calls nr_vowel([t,i,k],Z). However this time, when prolog tries to unify it with the second nr_vowel, vowel(t) returns false, so it unifies it with the third clause and behaves similarly until the list is empty.
As soon as the list is empty, prolog unifies Z with 0 and starts coming up the recursion levels and does N=N+1 depending on if the caller predicate had a vowel or not, and as soon as it reaches the top of the recursive chain, Z is unified with the final value of N.
In short -
N=N+1 happens if the head of the list is a vowel
N=N i.e. no change occurs if head of list is NOT a vowel.

Subtraction operation using only increment, loop, assign, zero

I am trying to build up subtraction, addition, division, multiplication and other operations using only following ones:
incr(x) - Once this function is called it will assign x + 1 to x
assign(x, y) - This function will assign the value of y to x (x = y)
zero(x) - This function will assign 0 to x (x = 0)
loop X { } - operations written within brackets will be executed X times
Using following rules it is straight forward to implement addition (add) like this:
ADD (x, y) {
loop X {
y = incr (y)
}
return y
}
However, I'm struggling to implement subtraction. I think that all the other needed operations could be completed using subtraction.
Any hint will be very appreciated.
Stephen Cole Kleene devised a way to perform integer subtraction using integer addition. However, it assumes that you cannot have negative integers. For example:
0 - 1 = 0
1 - 1 = 0
2 - 1 = 1
3 - 1 = 2
4 - 1 = 3
5 - 2 = 3
6 - 3 = 3
6 - 4 = 2
6 - 5 = 1
6 - 6 = 0
6 - 7 = 0
In your question, you implemented the addition operation using the increment operation.
Similarly, you can implement the subtraction operation using the decrement operation as follows:
sub(x, y) {
loop y
{ x = decr(x) }
return x
}
Now, all we need to do is implement the decrement operation.
This is where the genuis of Kleene shines:
decr(x) {
y = 0
z = 0
loop x {
y = z
z = incr(z)
}
return y
}
Here we've used all the four operations. This is how it works:
We have two base cases, y (the base case for 0) and z (the base case for 1):
y = 0 - 1 = 0
z = 1 - 1 = 0
Hence, we initialize them both to 0.
When x is 0 we run the loop 0 times (i.e. never) and then we simply return y = 0.
When x is 1 then we run the loop once, assign y = z and then simply return y = z = 0.
Notice that every time we run the loop y holds the result of the current iteration while z holds the result of the next iteration. This is the reason why we require two base cases. The decrement function is not a continuous function. It is a piecewise function:
decr(0) = 0
decr(n + 1) = n
Kleene realized this when he went to the dentist and the dentist extracted two of his teeth. He was frustrated while trying to solve this very problem and when the dentist extracted two of his teeth he realized that he required two base cases.

Scilab code giving submatrix incorrectly defined error

I am trying to plot a 3D graph between 2 scalars and one matrix for each of its entries. On compiling it is giving me "Submatrix incorrectly defined" error on line 11. The code:
i_max= 3;
u = zeros(4,5);
a1 = 1;
a2 = 1;
a3 = 1;
b1 = 1;
hx = linspace(1D-6,1D6,13);
ht = linspace(1D-6,1D6,13);
for i = 1:i_max
for j = 2:4
u(i+1,j)=u(i,j)+(ht*(a1*u(i,j))+b1+(((a2*u(i,j+1))-(2*a2*u(i,j))+(a2*u(i,j-1)))*(hx^-2))+(((a3*u(i,j+1))-(a3*u(i,j-1)))*(0.5*hx^-1)));
plot(ht,hx,u(i+1,j));
end
end
Full error message:
-->exec('C:\Users\deba123\Documents\assignments and lecture notes\Seventh Semester\UGP\Scilab\Simulation1_Plot.sce', -1)
+(((a3*u(i,j+1))-(a3*u(i,j-1)))*(0.5*hx^-1)))
!--error 15
Submatrix incorrectly defined.
at line 11 of exec file called by :
emester\UGP\Scilab\Simulation1_Plot.sce', -1
Please help.
For a 3-dimensional figure, you need 2 argument vectors and a matrix for the function values. So I expanded u to a tensor.
At every operation in your code, I added the current dimension of the term. Now, a transparent handling of you calculation is given. For plotting you have to use the plot3d (single values) or surf (surface) command.
In a 3-dim plot, you want two map 2 vectors (hx,ht) with dim n and m to an scalar z. Therefore you reach a (nxm)-matrix with your results. Is this, what you want to do? Currently, you have 13 values for each u(i,j,:) - entry, but you want (13x13) for every figure. Maybe the eval3d-function can help you.
i_max= 3;
u = zeros(4,5,13);
a1 = 1;
a2 = 1;
a3 = 1;
b1 = 1;
hx = linspace(1D-6,1D6,13); // 1 x 13
ht = linspace(1D-6,1D6,13); // 1 x 13
for i = 1:i_max
for j = 2:4
u(i+1,j,:)= u(i,j)...
+ ht*(a1*u(i,j))*b1... // 1 x 13
+(((a2*u(i,j+1)) -(2*a2*u(i,j)) +(a2*u(i,j-1)))*(hx.^-2))... // 1 x 13
+(((a3*u(i,j+1))-(a3*u(i,j-1)))*(0.5*hx.^-1)) ... // 1 x 13
+ hx*ones(13,1)*ht; // added to get non-zero values
z = squeeze( u(i+1,j, : ))'; // 1x13
// for a 3d-plot: (1x13, 1x13, 13x13)
figure()
plot3d(ht,hx, z'* z ,'*' ); //
end
end

get n dimensional Fortran array from subroutine output into R?

I have the following Fortran subroutine:
subroutine test(d, i, nMCd, DF, X)
integer, intent(in) :: d, i, nMCd
double precision, intent(in), dimension(i,nMCd) :: DF
double precision, intent(out), dimension(i) :: X
X = DF(:,d)+DF(:,d)
end subroutine test
I am able to compile it for R load it and run it. But instead of getting an array I'm getting a single number.
system("R CMD SHLIB ./Fortran/mytest.f90")
dyn.load("./Fortran/mytest.so")
input <- data.frame(A=c(11,12), B=c(21, 22))
.Fortran("test", d = as.integer(1), i = nrow(input), nMCd = ncol(input), DF = unlist(input), X = as.numeric(1))
What am I doing wrong?!
My output looks like
$d
[1] 1
$i
[1] 2
$nMCd
NULL
$DF
A1 A2 B1 B2
11 12 21 22
$X
[1] 22
The R version of this is:
input[,1]+input[,1]
I haven't figured out what this was supposed to do because I don't program in FORTRAN (And you didn't say what you expected in a language that I do read) but this is an experiment that delivers the sum of the items in the first columns of the input object, which might make some sense when I look at the code with the inputs. It seems possible that sending 1 for d to extract from DF(:,d)+ DF(:,d) might mean you wanted the sums of first columns. Notice that I just supplied an empty 4 element vector to X and made its Fortran dimensions the same as DF:
Source in file:
subroutine test(d, i, nMCd, DF, X)
integer, intent(in) :: d, i, nMCd
double precision, intent(in), dimension(i,nMCd) :: DF
double precision, intent(out), dimension(i,nMCd) :: X(i)
X = DF(:,d)+DF(:,d)
end subroutine test
R code:
input <- data.frame(A=c(11,12), B=c(21, 22))
.Fortran("test", d = as.integer(1), i = nrow(input), nMCd = ncol(input),
DF = unlist(input), X = numeric(4))
#--- result------
$d
[1] 1
$i
[1] 2
$nMCd
[1] 2
$DF
A1 A2 B1 B2
11 12 21 22
$X
[1] 22 24 0 0
Further experiment, still without any knowledge of Fortran, trying to add the items in the first row together:
X = DF(d,:)+DF(d,:)
Produced:
$X
[1] 22 42 0 0

Resources