I want to create successor Numbers from natural numbers in Prolog.
nat2s(0, s(0)).
nat2s(NaturalNumber, SNumber) :-
N is NaturalNumber - 1,
nat2s(N, s(SNumber)).
The output should be like this:
nat2s(3, X).
X = s(s(s(0))).
Actually it's an infinitive loop. I don't how to end the loop without only getting true as result.
I suggest a slightly different approach, namely the use of library(clpfd). First let's pick a more declarative name for the predicate. Since in your post the natural number and the number in s(X)-notation are the first and second argument respectively, let's call it nat_sx/2. Then the predicate can be defined like so:
:- use_module(library(clpfd)).
nat_sx(0,0).
nat_sx(N,s(X)) :-
N #> 0,
N0 #= N-1,
nat_sx(N0,X).
This yields the desired result in your post:
?- nat_sx(3,X).
X = s(s(s(0))) ? ;
no
To see why the use of clpfd is beneficial let's incorporate the suggested corrections from the comments into your code and compare both versions.
nat2s(0, 0).
nat2s(NaturalNumber, s(SNumber)) :-
NaturalNumber > 0,
N is NaturalNumber - 1,
nat2s(N, SNumber).
The above query works with this version as well:
?- nat2s(3,S).
S = s(s(s(0))) ? ;
no
However, it would be nice to be able to use the predicate in the other direction as well. So let's ask which natural number corresponds to s(s(0)):
?- nat_sx(N,s(s(0))).
N = 2 ? ;
no
?- nat2s(N,s(s(0))).
ERROR at clause 2 of user:nat2s/2 !!
INSTANTIATION ERROR- =:=/2: expected bound value
The reason for the instantiation error is the fact that is/2 expects a variable-free expression on the right side:
?- X is 3-1.
X = 2
?- 2 is X-1.
ERROR!!
INSTANTIATION ERROR- in arithmetic: expected bound value
?- 2 is 3-X.
ERROR!!
INSTANTIATION ERROR- in arithmetic: expected bound value
This is also the reason why the most general query of nat2s/2 has an instantiation error after the first solution...
?- nat2s(N,S).
N = S = 0 ? ;
ERROR at clause 2 of user:nat2s/2 !!
INSTANTIATION ERROR- =:=/2: expected bound value
... while nat_sx/2 keeps generating solutions:
?- nat_sx(N,S).
N = S = 0 ? ;
N = 1,
S = s(0) ? ;
N = 2,
S = s(s(0)) ? ;
...
Related
Many prolog guides use the following definition of negation as failure.
% negation as failure
negation(G) :- call(G), !, fail.
negation(_).
Question: is it necessary to wrap G in call/1?
In the following definition, G is written without wrapping it with a call/1, and it seems to work.
% negation as failure
negation2(G) :- G, !, fail.
negation2(_).
Testing with swi-prolog (swish):
?- negation2(true)
false
?- negation2(false)
true
I also tested it with a short prolog program.
Question 2: Are there scenarios when we must write call(G) and not simply G?
First of all, these examples are about programs that go beyond first order logic, for you now permit variables to be in the place of goals. Inevitably, this transition will lead to some quirks on its way.
The common way to resolve this in ISO (and also in many systems that are not ISO like SWI) is to define an exact moment where first-order terms are converted into a goal or body of a clause (7.6.2). In this moment, a variable G_0 that occurs in the place of a goal is wrapped into call(G_0).
Thus, to answer Q1: No, it is not necessary to wrap that variable in your definition of negation/1, since the term-to-body conversion is happening here at the time of the preparation for execution of this Prolog text.
So essentially there will never be a variable that is called directly. Instead, call/1 is used always.
Your question 2 thus boils down to: What is the difference between a non-variable term as a goal and that term just wrapped with call/1?
Terms that cannot be converted to a goal/body.
?- false, call(1).
false.
?- false, 1.
error(type_error(callable,(false,1)),(',')/2).
?- G_0 = ( false, call(1)), G_0.
false.
?- G_0 = ( false, 1), G_0.
error(type_error(callable,(false,1)),(',')/2).
Control constructs cut and if-then-else no longer cut.
?- ( !, false ; true ).
false.
?- ( call(!), false ; true ).
true.
?- ( A = 1 -> B = 2 ; C = 3 ).
A = 1, B = 2.
?- ( ( A = 1 -> B = 2 ) ; C = 3 ).
A = 1, B = 2.
?- ( call(( A = 1 -> B = 2 )) ; C = 3 ).
A = 1, B = 2
; C = 3.
Note that in SWI, the toplevel has its own extra error checking which sometimes shows. With an extra indirection this can be circumvented. Here is such a case:
?- false, unknown.
false. % result in Scryer etc
?- false, unknown.
ERROR: Unknown procedure: unknown/0 (DWIM could not correct goal)
% SWI result only
?- G_0 = ( false, unknown ), G_0.
false. % same result everywhere
I'm new in prolog, and I wanted to create a "function" to count how many different values I have in a list.
I've made this predicate to count the total number of values:
tamanho([],0).
tamanho([H|T],X) :- tamanho(T,X1), X is X1+1.
I wanted to follow the same line of thought like in this last predicate.(Don't know if that's possible).
So in a case where my list is [1,2,2,3], the answer would be 3.
Can someone give me a little help?
Here is a pure version which generalizes the relation. You can not only count but just see how elements have to look like in order to obtain a desired count.
In SWI, you need to install reif first.
:- use_module(library(reif),[memberd_t/3]).
:- use_module(library(clpz)). % use clpfd in SWI instead
:- op(150, fx, #). % backwards compatibility for old SWI
nt_int(false, 1).
nt_int(true, 0).
list_uniqnr([],0).
list_uniqnr([E|Es],N0) :-
#N0 #>= 0,
memberd_t(E, Es, T),
nt_int(T, I),
#N0 #= #N1 + #I,
list_uniqnr(Es,N1).
tamanho(Xs, N) :-
list_uniqnr(Xs, N).
?- tamanho([1,2,3,1], Nr).
Nr = 3.
?- tamanho([1,2,X,1], 3).
dif:dif(X,1), dif:dif(X,2).
?- tamanho([1,2,X,Y], 3).
X = 1, dif:dif(Y,1), dif:dif(Y,2)
; Y = 1, dif:dif(X,1), dif:dif(X,2)
; X = 2, dif:dif(Y,1), dif:dif(Y,2)
; Y = 2, dif:dif(X,1), dif:dif(X,2)
; X = Y, dif:dif(X,1), dif:dif(X,2)
; false.
You can fix your code by adding 1 to the result that came from the recursive call if H exists in T, otherwise, the result for [H|T] call is the same result for T call.
tamanho([],0).
tamanho([H|T], X) :- tamanho(T, X1), (member(H, T) -> X is X1; X is X1 + 1).
Tests
/*
?- tamanho([], Count).
Count = 0.
?- tamanho([1,a,21,1], Count).
Count = 3.
?- tamanho([1,2,3,1], Count).
Count = 3.
?- tamanho([1,b,2,b], Count).
Count = 3.
*/
In case the input list is always numerical, you can follow #berbs's suggestion..
sort/2 succeeds if input list has non-numerical items[1] so you can use it without any restrictions on the input list, so tamanho/2 could be just like this
tamanho(T, X) :- sort(T, TSorted), length(TSorted, X).
[1] thanks to #Will Ness for pointing me to this.
Need help creating a recursive clause is a rule: X is a power of 2 only if there is a Y such that when adding Y to Y the result is
X, and Y is a power of 2. in prolog
We are going to define this predicate recursively. The followings are the fact and rule for detecting whether a numeral
is a power of 2 or not:
• The base clause is a fact: 1 is a power of 2 (because 1=20);
• The recursive clause is a rule: X is a power of 2 only if there is a Y such that when adding Y to Y the result is
X, and Y is a power of 2.
For example, the following shows how the queries should be performed:
| ?- powerOf2(succ(succ(succ(succ(0))))).
true ?
yes
| ?- powerOf2(succ(succ(succ(0)))).
no
The first query shows that 4 is a power of 2; while the second shows that 3 is not.
can not use the built-in is/2 predicate to perform arithmetic
To make it easier to represent natural numbers in Peano notation, you can use the following predicate:
nat(0, 0).
nat(N, s(P)) :-
succ(M, N),
nat(M, P).
Examples:
?- nat(3, P).
P = s(s(s(0))) ;
false.
?- nat(5, P).
P = s(s(s(s(s(0))))) ;
false.
To get the double of a Peano number, use the predicate:
double(0, 0).
double(s(A), s(s(B))) :-
double(A, B).
Examples:
?- nat(1, P), double(P, D).
P = s(0),
D = s(s(0)) ;
false.
?- nat(3, P), double(P, D).
P = s(s(s(0))),
D = s(s(s(s(s(s(0)))))) ;
false.
To check whether a Peano number is a power of two, use the predicate:
power_of_two(s(0)).
power_of_two(s(s(N))) :-
double(M, s(s(N))),
power_of_two(M).
Example:
?- between(1,9,N), nat(N,P), power_of_two(P).
N = 1,
P = s(0) ;
N = 2,
P = s(s(0)) ;
N = 4,
P = s(s(s(s(0)))) ;
N = 8,
P = s(s(s(s(s(s(s(s(0)))))))) ;
false.
Need help creating a recursive clause
The recursive clause will be:
power_of_two(1).
power_of_two(X) :-
X > 1,
Y is X / 2,
power_of_two(Y).
A base case which handles 1 being a power of two. And a case which handles when X is greater than one, Y is half X and recursively checks that Y is a power of two.
can not use the built-in is/2 predicate to perform arithmetic
You can't, but I can for the sake of illustrating the recursive clause you asked about. I'm assuming that since it tells you to use "succ(succ(succ(succ(0))))" you already have met that and have some code for adding/subtracting/dividing which you can reuse to replace Y is X / 2.
I need to get the index of a term's argument in Prolog. Predicate arg/3 seems to do the opposite of what I need:
arg(Index, Term, Value).
arg/3 fails if Index is a variable, so it's not possible to get the index of a given value and term. You guys know any other way to achieve this (I can't use external libraries)?
An example of the expected behaviour would be:
?- arg_(Index, regs(a,b,c), c).
Index = 3
Not all Prolog implementations seem to behave like SWI-Prolog does when the index is a variable. Its behavior might be an extension to the standard.
Here is what GNU Prolog 1.4.5 does:
| ?- arg(Index,s(a,b,c,d),V).
uncaught exception: error(instantiation_error,arg/3)
| ?- arg(Index,regs(a,b,c),c).
uncaught exception: error(instantiation_error,arg/3)
So you'll have to backtrack over the valid indices yourself. You can use functor/3 to find out how many arguments there are:
| ?- Term = regs(a,b,c), functor(Term, _Functor, Arity).
Arity = 3
Term = regs(a,b,c)
yes
And many Prologs (including GNU Prolog) have a between/3 predicate for enumerating integers in a range:
| ?- between(1, 4, N).
N = 1 ? ;
N = 2 ? ;
N = 3 ? ;
N = 4
(1 ms) yes
So overall you can do:
| ?- Term = regs(a,b,c), functor(Term, _Functor, Arity), between(1, Arity, Index), arg(Index, Term, Value).
Arity = 3
Index = 1
Term = regs(a,b,c)
Value = a ? ;
Arity = 3
Index = 2
Term = regs(a,b,c)
Value = b ? ;
Arity = 3
Index = 3
Term = regs(a,b,c)
Value = c
yes
I have some problems with prolog, specifically I can't compare a value of a predicate with a constant.
predicate(9).
compare(X,Y) :- X<Y.
Running the program:
?-compare(predicate(X),10).
Why doesn't it work? Thank you for your answers.
Predicates don't return values in the way that a function does.
This is C:
int nine() { return 9; }
int main() {
int x = nine(); /* x is now 9 */
}
This is Prolog:
% source
nine(9).
% from the top level
?- nine(X).
X = 9.
?- nine(X), X < 10.
X = 9.
?- nine(X), compare(C1, X, 10), compare(C2, 10, X).
X = 9,
C1 = (<),
C2 = (>).
Few things (trying not to use too much Prolog lingo):
What your predicate/1 and my nine/1 does is to unify its only argument with the integer 9. If the unification succeeds, the predicate succeeds, and now the argument is bound to 9. If the unification fails, the predicate fails.
?- nine(9).
true.
?- nine(nine).
false.
?- nine(X), nine(Y).
X = Y, Y = 9.
You will also notice that there is a standard predicate compare/3 that can be used for comparison of Prolog terms. Because predicates don't have a return value in the way that functions do, it uses an extra argument to report the result of the comparison. You could have instead tried something along the lines of:
% greater_than(X, Y) : true if X is greater than Y according
% to the standard order of terms
greater_than(X, Y) :- X #> Y.
But this is just defining an alias for #>/2, which is a predicate itself (but has been declared as an operator so that you can use it in infix notation).
?- #>(a, b).
false.
?- #>(b, a).
true.
Same goes for </2, which is a predicate for comparison of arithmetic expressions:
?- 2 + 4 =< 6.
true.
?- nine(X), X > 10 - X.
X = 9.
?- nine(X), X > 10.
false.
Like #Boris said before "Predicates don't return values in the way that a function does." Here you must try to instantiate the variables in the head of your rule.
If you are trying with you predicate compare/2 to find a number X greater than Y, and at the same time this number X should be a fact predicate/1, then add both conditions to the body of your rule or predicate compare/2
predicate(9).
compare(X,Y) :- predicate(X), X<Y.
Now if you consult:
?- compare(X,10).
The answer will be
X = 9
As you can see, 9 is smaller than 10, and at the same time 9 is a fact predicate/1. And that is the return value you are looking for.
Caution
Note that the operator >/2, requires that both sides are instantiated, so in this case you won't be able ask for the value Y in your predicate
?- compare(9, Y)
</2: Arguments are not sufficiently instantiated
Maybe and if it make sense, you can try to instantiate this variable to a fact predicate/1 too.
predicate(9).
predicate(10).
compare(X,Y) :- predicate(X), predicate(Y), X<Y.
?- compare(9,Y).
Y = 10