List 插入到开放式列表中而不绑定其尾部变量

List 插入到开放式列表中而不绑定其尾部变量,list,prolog,instantiation-error,List,Prolog,Instantiation Error,是否可以在Prolog中解决以下问题 让A和B成为数字列表,让N成为数字。众所周知,B的排序是递减的。检查N是否可以插入A中,以使结果为B,但不要绑定A或B中作为尾部出现的任何变量 比如说 ?- insertable(34, [78, 72, 11 | Z], [78, 72, 34, 11 | Z]). true. ?- insertable(34, [78, 72, 11 | Z], L). L = [78, 72, 34, 11 | Z]. 有人能帮我吗?:) 编辑1:这就是我想到的

是否可以在
Prolog
中解决以下问题

A
B
成为数字列表,让
N
成为数字。众所周知,
B
的排序是递减的。检查
N
是否可以插入
A
中,以使结果为
B
,但不要绑定
A
B
中作为尾部出现的任何变量

比如说

?- insertable(34, [78, 72, 11 | Z], [78, 72, 34, 11 | Z]).
true. 

?- insertable(34, [78, 72, 11 | Z], L).
L = [78, 72, 34, 11 | Z].
有人能帮我吗?:)

编辑1:这就是我想到的

insertable(X, List1, List2):- select(X, List2, List1), sorted(List2).

sorted([]).
sorted([_]).
sorted([X, Y | Rest]) :-
  X > Y,
  sorted([Y | Rest]).
但是,即使在参数完全实例化时,它仍能按预期工作,但它会绑定位于尾部的变量:

?- insertable(11, [5, 3, 2], [11, 5, 3, 2]).
true .

?- insertable(11, [5, 3, 2 | X], [11, 5, 3, 2 | X] ).
X = [] .

?- insertable(11, [5, 3, 2 | X], L ).
X = [],
L = [11, 5, 3, 2] .
编辑2:这是我尝试过的另一种方法

in(X, [], [X]).
in(X, [Head | Tail1], [Head | Tail2]) :-
  X =< Head,
  in(X, Tail1, Tail2).
in(X, [Head | Tail], [X, Head | Tail]) :-
  X > Head.
in(X,[],[X])。
在(X,[Head | Tail1],[Head | Tail2])中:-
X=
问题仍然存在:

?- in(1, [3, 2], [3, 2, 1]).
true ;
false.

?- in(1, [3, 2], L).
L = [3, 2, 1] ;
false.

?- in(1, [3, 2 | X], L).
X = [],
L = [3, 2, 1] ;
ERROR: =</2: Arguments are not sufficiently instantiated
   Exception: (9) in(1, _G8394089, _G8394190) ? abort
% Execution Aborted
?- in(1, [3, 2 | X], [3, 2, 1 | X]).
X = [] ;
X = [1] ;
X = [1, 1] ;
X = [1, 1, 1] ;
X = [1, 1, 1, 1] ;
X = [1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 1, 1] ;
X = [1, 1, 1, 1, 1, 1, 1] .
?-in(1[3,2],[3,2,1])。
是的;
错。
?-in(1,[3,2],L)。
L=[3,2,1];
错。
?-in(1,[3,2 | X],L)。
X=[],
L=[3,2,1];

错误:=这个练习的技巧是元谓词
var/1
nonvar/1
,如果参数是变量或不是变量,它们都是真的(还可以查看
ground/1
atom/1
integer/1
)。要做到这一点有点笨拙,因为我们需要将列表
L1
保留在头脑中,并在知道它是否是变量后统一起来


同样让您困惑的是算术比较的错误消息。这两个论点都必须有根据。当您不测试尾部的非var时,统一会自动用
[Head | Tail1]
实例化尾部。这总是导致一个比较
数字,我认为如果你只是尝试实现它,而不太担心你试图保存的属性,你会发现它会自然而然地消失。你试过什么?嗨,丹尼尔斯。我添加了我设法编写的代码。你能看一下吗?你的列表总是有一个未实例化的变量作为尾部吗?
insert(10,[11 | Z],X)
成功还是失败?@williness不,它们的尾部并不总是有一个未实例化的变量
insert(10,[11 | Z],X)
应该成功地将
X
[11,10 | Z]
统一起来。但是你说过尾部不应该改变。(??)你的意思是名单应该保持开放,但也允许在尾部增长吗?
in(X, L1, [X]) :- % terminal case for empty list (i.e. tail is not a variable)
    nonvar(L1),
    L1 = [].
in(X, Xs, [X | Xs]) :- % terminal case if the tail is a variable
    var(Xs).
in(X, L1, [N | Zs]) :- % recursive case X =< N
    nonvar(L1),
    L1 = [N | Ys],
    X =< N,
    in(X, Ys, Zs).
in(X, L1, [X,  N | Ys]) :- % recursive case X > N
    nonvar(L1),
    L1 = [N | Ys],
    X > N.
?- in(1,Xs,Ys).
Ys = [1|Xs] ;
false.
?- in(1,Xs,[2|Ys]).
false.
?- in(1,[3, 2 | Xs], Zs).
Zs = [3, 2, 1|Xs] ;
false.
?- in(2,[3,1 |Xs],Zs).
Zs = [3, 2, 1|Xs].
?- in(34, [78, 72, 11 | Z], [78, 72, 34, 11 | Z]).
true ;
false.
?- in(2,[3,A,1|Xs],Zs).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [10] 2=<_8374
ERROR:    [9] in(2,[_8406,1|_8414],[_8418|_8420]) at ./prolog/so-3.pl:9
ERROR:    [8] in(2,[3,_8458|...],[3,_8470|_8472]) at ./prolog/so-3.pl:10
ERROR:    [7] <user>
   Exception: (9) in(2, [_7488, 1|_7496], _7820) ? a
?- in(2,[3,A,1|Xs],Zs).
false.