Prolog Assigning integer to a variable

2019-07-24 07:54发布

I'm new to Prolog, and using GNU Prolog, so no clp(fd) allowed. What I'm trying to do is for a given integer N, generate a list with elements of 1 ~ N. So set(3,T). will output T = [1,2,3]. Here is what I have so far:

set(0,[]).
set(N,T):-set(N-1,T1),append(T1,[N],T).

When I try set(2,T), it crashes. I debugged with trace, and find out that it's not evaluating N-1, but rather doing N-1-1-1...

Anyone can tell me how to solve this? Thank you.

标签: prolog
2条回答
一纸荒年 Trace。
2楼-- · 2019-07-24 08:29
n_ups(N, Xs) :-
   length(Xs, N),
   numbered_from(Xs, 1).

numbered_from([], _).
numbered_from([I0|Is], I0) :-
   I1 is I0+1,
   numbered_from(Is, I1).

In fact, the complexity is hidden within length/2.

查看更多
做个烂人
3楼-- · 2019-07-24 08:38

It should be:

set(N,T):- N2 is N-1, set(N2,T1), append(T1,[N],T).

Arithmetic operations are performed by using is/2. N-1 is a shorthand for -(N,1) (just like N2 is N-1 is shorthand for is(N2, N-1)), so you were just creating infinite tree -(-(-(-(...),1),1,1,1).

Little educational note:

If you want set/2 to be proper relation so it can answer queries like set(3,X), set(X, [1,2,3]) and set(X,Y) without error then you should write this predicate that way:

set(0, []).
set(Value, List) :-
  length(List, Value),
  append(ShorterList, [Value], List),
  ValueMinusOne is Value - 1,
  set(ValueMinusOne, ShorterList).

That way result of arithmetic operation is always possible to obtain because input value (lenght of the list) is either explicitly given or generated from length/1.

查看更多
登录 后发表回答