I tried this
fun([],[]).
fun([A|_],B) :- number(A), B is A +1,!.
fun([H|T],R) :- fun(T,R).
I know it's wrong, could you help me? Thanks
I tried this
fun([],[]).
fun([A|_],B) :- number(A), B is A +1,!.
fun([H|T],R) :- fun(T,R).
I know it's wrong, could you help me? Thanks
For seeing that your program cannot work, you can either try it out:
?- fun([1],L).
L = 2.
?- fun([1],[]).
true.
?- fun([X],L).
L = [].
So this shows clearly non-relational behavior: In the first query we ask for an L
and get L = 2
as an answer, but then we ask about []
being an answer ; and the system accepts that too. Clearly, your definition cannot be a relation. The culprit is certainly the cut.
Apart from that, there are also other ways to see problems. It suffices to look at one rule alone. The first rules (fun([A|_],B) :- number(A), B is A +1,!.
) says that the second argument must be an integer (in certain situations). But it should be a list. The second rule (fun([H|T],R) :- fun(T,R).
) says that any element can be skipped. Clearly that cannot be part of a meaningful definition.
The most concise way would use the higher-order predicate maplist/3
and lambda expressions as defined in library(lambda). Written this way, an intermediary predicate is usually not used.
fun(Xs, Ys) :-
maplist(\X^Y^(Y is X+1), Xs, Ys).
The next version avoids lambdas and uses a concrete definition instead:
msucc(X, Y) :-
Y is X+1.
fun(Xs, Ys) :-
maplist(msucc, Xs, Ys).
In fact, there is a predefined predicate succ/2
which is present in many Prologs and is part of the Prolog prologue.
fun(Xs, Ys) :-
maplist(msucc, Xs, Ys).
The most "pedestrian" way of defining it would be directly with a predicate definition:
fun([], []).
fun([X|Xs], [Y|Ys]) :-
Y is X+1,
fun(Xs, Ys).
Which one do you prefer?
For more about the maplist-family: Prolog map procedure that applies predicate to list elements
If you want to learn Prolog, stick to to pure relations first. Avoid the cut. Avoid side effects like write
. Avoid even (is)/2
. Use successor-arithmetics and later clpfd. Study termination and non-termination failure-slice, and dcg.
The problem is that you're not consistent and you're not finishing the recursion.
With your code, something like this is true:
fun([a,b,c],X) .
and will result in X having the value []
, but
fun([a,1,b],X) .
will result in X having the value 2
.
If you want to find the first number in the list and increment it by one, something like this will do:
fun([X|Xs],Y) :- number(X) , ! , Y is X+1 .
fun([_|Xs],Y) :- fun(Xs,Y) .
If you want to increment each number in the list, then try something like this:
fun( [] , [] ) . % if the source list is exhausted, we're done.
fun( [X|Xs] , [Y|Ys] ) :- % otherwise,
number(X) , % - if X is a number,
Y is A+1 % - we increment it to get Y
fun( Xs , Ys ) . % - and recurse down on the tails of the respective lists
fun( [X|Xs] , [X|Ys] ) :- % otherwise, add X to the result list
\+ number(X) , % - assuming X is not a number,
fun(Xs,Ys) . % - and recurse down.
You should not that this could be more concisely states as
fun( [] , [] ) :-
fun( [X|Xs] , [Y|Ys] ) :-
increment(X,Y) ,
fun( Xs , Ys )
.
increment(X,Y) :- number(X) , ! , Y is X+1 .
increment(X,X) .
Or, more concisely yet
fun( [] , [] ) .
fun( [X|Xs] , [Y|Ys] ) :-
( number(X) -> Y is X+1 ; Y = X ) ,
fun(Xs,Ys).
The A -> B ; C
construct is the implication operator.