i want to know if there are any methods to achieve an iteration in Prolog passing an empty input. For example I would like to have 0 on the first iteration, 1 on the next one, 2 on the second one and so on.
From your comment:
Example: iterate() is my query and every time i call it i want that the output is 0 first time 1 second time and so on.
Shouldn't be any more difficult than this:
increment(N) :- inc(0,1,N).
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C+S, inc(C1,S,N).
To break it down, a very common idiom in Prolog programming is the use of helper predicates. Since prolog doesn't have any sort of iteration construct, it just has recursion and backtracking, often to do something useful, you'll need to carry additional state as you go: things like the current value of a counter, etc.
So . . .
We have our increment/1 predicate. All it does is invoke a helper predicate, inc/3. It carries, in addition to the variable from the calling predicate (N), two additional pieces of state:
The current value (C) of a counter, and
The step value (S), that value by which the counter should be incremented in each recursive call.
Those bits of state are initialized with 0 and 1 respectively.
inc/3, our helper predicate has just two clauses:
inc(C , _ , C ) .
inc(C , S , N ) :- C1 is C+S, inc(C1,S,N).
What it does is this:
On initial entry to the predicate, the 1st clause of the predicate is entered, and current value of the counter is unified with N, the desired value, and succeeds.
On backtracking, that unification is undone, and the 2nd clause of the predicate is entered. That does the following:
The next value (C1) is computed as the sum of the current and step values.
inc/3 is recursively invoked, passing C1, S, and N.
You might note that this predicate is non-terminating: If you were to run inc(0,1,N), writeln(N), fail, your CPU would spin to 100% as it started writing to the console
0
1
2
3
4
. . .
Similar question
With succ/2:
nat(N) :-
nat(0, N).
nat(N, N).
nat(N0, N) :-
succ(N0, N1),
nat(N1, N).
Or with call_nth/2:
nat(0).
nat(N) :-
call_nth(repeat, N).
Now, all natural numbers:
?- nat(N).
Example: iterate() is my query and every time i call it i want that the output is 0 first time 1 second time and so on.
If you store the state in the Prolog database and don't mind the output being by side effect and can deal with not using () when calling it, then:
:- dynamic(iterate_counter/1).
iterate_counter(0).
iterate() :-
iterate_counter(X),
writeln(X),
succ(X, Y),
retract(iterate_counter(X)),
assert(iterate_counter(Y)).
?- iterate, iterate, iterate.
0
1
2
incrementing(Lower, Increment, N) :-
integer(Lower),
integer(Increment),
% Fast integer comparison
Increment #>= 1,
incrementing_(Lower, Increment, N).
incrementing_(Lower, Increment, N) :-
nonvar(N), !,
integer(N),
% Can calculate, faster than iterating
N #>= Lower,
Diff is N - Lower,
divmod(Diff, Increment, _, 0).
incrementing_(Lower, Increment, N) :-
incrementing_loop_(Lower, Increment, N).
incrementing_loop_(Lower, _Increment, Lower).
incrementing_loop_(Lower, Increment, N) :-
Lower1 is Lower + Increment,
incrementing_loop_(Lower1, Increment, N).
Results in swi-prolog:
?- incrementing(5, 3, N).
N = 5 ;
N = 8 ;
N = 11 ;
N = 14 ...
?- incrementing(5, 3, 11).
true.
?- incrementing(5, 3, 12).
false.
Could wrap this, for convenience, e.g.:
iterate(N) :-
incrementing(0, 1, N).
Results:
?- iterate(-1).
false.
?- iterate(2).
true.
?- iterate(N).
N = 0 ;
N = 1 ;
N = 2 ;
N = 3 ...
Related
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.
I'm trying to implement a method to work as follows foo(5) = 5^4 + 4^3 + 3^2 + 2^1 + 1^0 = 701 using recursion. I've been trying to follow the logic but I keep getting errors. can someone guide me?
(define (foo n) ; size-n problem
( cond ( (= (- n 1) 0 ) ; stopping condition
0 ); return value
(else (+ ( expt n (- n 1) ) ( foo (- n 1) ) ) ))) ; size-m problems
If you tagged the question correctly, you want to answer this in Prolog, but your code fragment suggests you use lisp (or a language that I don't know).
In Prolog you write predictes. For your problem, there are two cases:
The case where N is less than or equal to zero, which is zero:
foo(N,0) :-
N =< 0,
!.
The inductive case when N is greater than 0. In that case we calculate foo for N-1 and add up N^(N-1):
foo(N,S) :-
N1 is N-1,
foo(N1,T),
S is T+N^N1.
You can simply write program containing the two cases:
foo(N,0) :-
N =< 0,
!.
foo(N,S) :-
N1 is N-1,
foo(N1,T),
S is T+N^N1.
And test it as follows:
?- foo(-1,S).
S = 0.
?- foo(0,S).
S = 0.
?- foo(1,S).
S = 1.
?- foo(2,S).
S = 3.
?- foo(3,S).
S = 12.
?- foo(5,S).
S = 701.
You can akso make th is predicate more safer from looping by adding a check for the inductive case:
foo(N,0) :-
N =< 0,
!.
foo(N,S) :-
N > 0,
N1 is N-1,
foo(N1,T),
S is T+N^N1.
Or you can further boost the predicate's performance using an accumulator:
foo(N,S) :-
foo(N,0,S).
foo(N,S,T) :-
N > 0,
!,
N1 is N-1,
Q is S+N^N1,
foo(N1,Q,T).
foo(N,S,S) :-
N =< 0.
This version also checks first whether N > 0 before N =< 0 because it is a much more likely scenario: after one N =< 0 we stop recursion whereas the N > 0 will be called N-1 times. Using an accumulator enables a optimization technique called tail recursion.
I have the following recursion rules which returns the sum of a number, but I don't know how does it return the sum:
sum(1,1).
sum(A,Result) :-
A > 0,
Ax is A - 1,
sum(Ax,Bx),
Result is A + Bx.
now when you execute the following command in Prolog:
sum(3,X).
the answer will be 5, but as I look into the rules, I can't see how does these rules return values and sum the. How is the value of Bx is calculated ?
sum(3,X). actually gives a result of X = 6. This predicate (sum(N, X)) computes the sum of integers from 1 to N giving X:
X = 1 + 2 + 3 + ... + N.
So it is the sum of the integers from 1 to N.
sum(1,1) says the sum of 1 by itself is just 1. This is true. :)
The second clause should compute the sum for A > 1, but it's actually not totally properly written. It says A > 0 which is ignoring the fact that the first clause already takes care of the case for 1. I would have written it with A > 1. It will work as is, but be a little less efficient.
sum(A,Result) :-
A > 0,
Ax is A - 1,
sum(Ax, Bx), % Recursively find the sum of integers 1 to A-1
% Instantiate Bx with that sum
Result is A + Bx. % Result is A plus sum (in Bx) from 1 to A-1
This clause recursively says that the sum of integers from 1 to A is Result. That Result is the sum of A and the sum of integers from 1 to A-1 (which is the value Ax is unified to). The Bx is the intermediate sum of integers 1 through Ax (A-1). When it computes the sum(Ax, Bx), the value of Ax is 1 less than A. It will continue calling this second clause recursively until the first parameter goes down to 1, at which point the first clause will provide the value for the sum, and the recursion will unravel from there, summing 1, 2, 3, ...
EDIT: More Details on the Recursion
Let's look at sum(3,X) as an example.
sum(3,X) doesn't match sum(1,1). so that clause is skipped and Prolog looks at sum(A, Result). Prolog matches this by instantiating A as 3 and Result as X and steps through the statements making up the clause:
% SEQUENCE 1
% sum(A, Result) query issued with A = 3
3 > 1, % true
Ax is 3 - 1, % Ax is instantiated as the value 2
sum(2, Bx), % recursive call to `sum`, `Ax` has the value of 2
Result is 3 + Bx. % this statement is awaiting the result of `sum` above
At this point, Prolog suspends computing Result is A + Bx in order to make the recursive call. For the recursive call, Prolog can't match sum(Ax, Bx) to sum(1,1) because Ax is instantiated as 2. So it goes on to the next clause, sum(A, Result) and can match if it instantiates A as 2 and Result as Bx (remember, this is a new call to this clause, so these values for A and Result are a different copy than the ones we "suspended" above). Now Prolog goes through sum(A, Result) statements again, this time with the new values:
% SEQUENCE 2
% sum(A, Result) query issued with A = 2
2 > 0, % true
Ax is 2 - 1, % Ax is instantiated to the value 1
sum(1, Bx), % recursive call to `sum`, `Ax` has the value of 1
Result is 2 + Bx. % this statement is awaiting the result of `sum` above
Now Prolog has sum(1, Bx) (Ax is instantiated with 1). This will match sum(1,1) and instantiate Bx with 1 in the last query to sum above in SEQUENCE 2. That means Prolog will complete the sequence:
Result is 2 + 1. % `A` is 2 and `Bx` is 1, so `Result` is 3
Now that this result is complete, the recursive query to sum in the prior execution in SEQUENCE 1 will complete in a similar fashion. In this case, it is instantiated Bx with 3:
Result is 3 + 3. % `A` is 3 and `Bx` is 3 (from the SEQUENCE 2 query)
% so `Result` is 6
And finally, the original query, sum(3, X) completes, where X is instantiated with the result of 6 and you get:
X = 6.
This isn't a perfect explanation of how the recursion works, and there are some texts around with graphical representations that help. But I hope this provides some insight into how it operates.
I have a set of problems that I've been working through and can't seem to understand what the last one is asking. Here is the first problem, and my solution to it:
a) Often we are interested in computing ∑i=m..n f(i), the sum of function values f(i) for i = m through n. Define sigma f m n which computes ∑i=m..n f(i). This is different from defining sigma (f, m, n).
fun sigma f m n = if (m=n) then f(m) else (f(m) + sigma f (m+1) n);
The second problem, and my solution:
b) In the computation of sigma above, the index i goes from current
i to next value i+1. We may want to compute the sum of f(i) where i
goes from current i to the next, say i+2, not i+1. If we send this
information as an argument, we can compute more generalized
summation. Define ‘sum f next m n’ to compute such summation, where
‘next’ is a function to compute the next index value from the
current index value. To get ‘sigma’ in (a), you send the successor
function as ‘next’.
fun sum f next m n = if (m>=n) then f(m) else (f(m) + sum f (next) (next(m)) n);
And the third problem, with my attempt:
c) Generalizing sum in (b), we can compute not only summation but also
product and other forms of accumulation. If we want to compute sum in
(b), we send addition as an argument; if we want to compute the
product of function values, we send multiplication as an argument for
the same parameter. We also have to send the identity of the
operator. Define ‘accum h v f next m n’ to compute such accumulation,
where h is a two-variable function to do accumulation, and v is the
base value for accumulation. If we send the multiplication function
for h, 1 for v, and the successor function as ‘next’, this ‘accum’
computes ∏i=m..n f(i). Create examples whose ‘h’ is not addition or
multiplication, too.
fun accum h v f next m n = if (m>=n) then f(m) else (h (f(m)) (accum (h) (v) (f) (next) (next(m)) n));
In problem C, I'm unsure of what i'm suppose to do with my "v" argument. Right now the function will take any interval of numbers m - n and apply any kind of operation to them. For example, I could call my function
accum mult (4?) double next3 1 5;
where double is a doubling function and next3 adds 3 to a given value. Any ideas on how i'm suppoes to utilize the v value?
This set of problems is designed to lead to implementation of accumulation function. It takes
h - combines previous value and current value to produce next value
v - starting value for h
f - function to be applied to values from [m, n) interval before passing them to h function
next - computes next value in sequence
m and n - boundaries
Here is how I'd define accum:
fun accum h v f next m n = if m >= n then v else accum h (h (f m) v) f next (next m) n
Examples that were described in C will look like this:
fun sum x y = x + y;
fun mult x y = x * y;
fun id x = x;
accum sum 0 id next 1 10; (* sum [1, 10) staring 0 *)
accum mult 1 id next 1 10; (* prod [1, 10) starting 1 *)
For example, you can calculate sum of numbers from 1 to 10 and plus 5 if you pass 5 as v in first example.
The instructions will make more sense if you consider the possibility of an empty interval.
The "sum" of a single value n is n. The sum of no values is zero.
The "product" of a single value n is n. The product of no values is one.
A list of a single value n is [n] (n::nil). A list of no values is nil.
Currently, you're assuming that m ≤ n, and treating m = n as a special case that returns f m. Another approach is to treat m > n as the special case, returning v. Then, when m = n, your function will automatically return h v (f m), which is the same as (f m) (provided that v was selected properly for this h).
To be honest, though, I think the v-less approach is fine when the function's arguments specify an interval of the form [m,n], since there's no logical reason that such a function would support an empty interval. (I mean, [m,m−1] isn't so much "the empty interval" as it is "obvious error".) The v-ful approach is chiefly useful when the function's arguments specify a list or set of elements in some way that really could conceivably be empty, e.g. as an 'a list.
Okay, so I'm a beginner in Prolog so I'm sorry if I can't quite get my question across very clearly but this is where I'm struggling:
divide_by(X, D, I, R) :- (D > X), I is 0, R is X.
divide_by(X, D, I, R) :-
X >= D,
X_1 is X - D,
I_1 is I + 1,
divide_by(X_1, D, I_1, R),
R is X_1.
I'm trying to write a program that will accept two arguments (X and D) and return the Iterations (I) and Remainder (R) so that it can display the result of X / D when the user enters:
divide_by(8,3,I,R). for example.
When tracing the code I know that I is incorrect because the first increment makes it equal to 0 and so the count for that is wrong. But I don't know how to declare I is 0 without it resetting every time it recurses through the loop. (I don't want to declare I as 0 in the query)
I also realised that when it has finished recursing (when X < D) then I is going to be set to 0 because of the base case.
Would anyone be kind enough to show me how I can fix this?
You need to introduce an accumulator and use a helper predicate, something like this:
divide(_,0,_,_) :- !, fail . % X/0 is undefined and so can't be solved.
divide(0,_,0,0) :- !. % 0/X is always 0.
divide(X,Y,Q,R) :- % the ordinary case, simply invoke the
divrem(X,Y,0,Q,R) % helper with the accumulator seeded with 0
.
divrem(X,Y,Q,Q,X) :- % if X < Y, we're done.
X < Y . %
divrem(X,Y,T,Q,R) :- % otherwise...
X >= Y , % as long as X >= Y,
X1 is X - Y , % compute the next X
T1 is T + 1 , % increment the accumulator
divrem(X1,Y,T1,Q,R) % recurse down
. % Easy!