Prolog 序言:将列表复制到已分配的列表

Prolog 序言:将列表复制到已分配的列表,prolog,Prolog,我正在努力做一些我觉得应该很简单的事情,但似乎不在序言中!我想使List2等于List1,其中List2在过去已经被赋值(即它不是一个变量) 如果List2是一个变量,我可以简单地统一List1和List2: List2=List1. 但是在我的例子中,List2已经存在(并且不等于List1),因此这个谓词失败 我还尝试了以下方法: copy(List1,List2). copy(L,R) :- CCp(L,R). CCp([],[]). CCp([H|T1],[H|T2]) :- CCp(

我正在努力做一些我觉得应该很简单的事情,但似乎不在序言中!我想使List2等于List1,其中List2在过去已经被赋值(即它不是一个变量)

如果
List2
是一个变量,我可以简单地统一
List1
List2

List2=List1.
但是在我的例子中,
List2
已经存在(并且不等于
List1
),因此这个谓词失败

我还尝试了以下方法:

copy(List1,List2).
copy(L,R) :- CCp(L,R).
CCp([],[]).
CCp([H|T1],[H|T2]) :- CCp(T1,T2).
add_to_list(List2,List1):-
generateL(L),
( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
但这也失败了,大概是出于同样的原因

有人能把我引向正确的方向吗?我在自学序言,如果我忽略了一些简单的东西,我深表歉意。谢谢


背景:

每次运行谓词
add_to_list
时,我都试图将术语
L
添加到列表
List2
。到目前为止,我有以下几点:

copy(List1,List2).
copy(L,R) :- CCp(L,R).
CCp([],[]).
CCp([H|T1],[H|T2]) :- CCp(T1,T2).
add_to_list(List2,List1):-
generateL(L),
( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
所以我希望有一种方法可以重新分配List2,使其与List1相等,但这可能不是Prolog的思维方式

相反,我现在尝试按如下方式通过列表1:

my_predicate(List1,ListOut):-
    add_to_list(List1,ListOut),
    write(ListOut),nl,nl.

add_to_list(List2,List1):-
   generateL(L),
   ( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
 my_predicate(List2,Num):-
     add_to_list(List2,List1),
     (  Num_new < 99 -> my_predicate(List1,Num_new) ; true  ).

 add_to_list(List2,List1):-
     generateL(L),
     ( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
当我按如下方式调用
my_谓词时,这会起作用:my_谓词([],ListOut),即List1是空的(与开头一样)。但我现在希望能够使用
my\u谓词(List1,ListOut)
调用
my\u谓词
的后续时间,以便将预先存在的
List1
作为输入。

在绑定变量后不能“修改”变量。举例说明:

当在两个已经绑定的变量上执行规则“copy”或“ccp”时,prolog将验证它们是否相等,如果不相等则失败,但不会重新分配。如果他们中的一些人不受约束,这将使他们平等。如果其中一些部分未绑定(一些列表项未绑定),它将使未绑定项相等,并验证剩余项


如果您介绍了问题的全部背景,我们可以提出备选方案。

感谢您引导我朝着正确的方向前进-最后我通过递归调用
我的谓词
解决了问题,如下所示:

my_predicate(List1,ListOut):-
    add_to_list(List1,ListOut),
    write(ListOut),nl,nl.

add_to_list(List2,List1):-
   generateL(L),
   ( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
 my_predicate(List2,Num):-
     add_to_list(List2,List1),
     (  Num_new < 99 -> my_predicate(List1,Num_new) ; true  ).

 add_to_list(List2,List1):-
     generateL(L),
     ( \+ memberchk(L,List2) -> List1=[L|List2]  ; List1 = List2).
my_谓词(List2,Num):-
将_添加到_列表(列表2,列表1),
(Num_new<99->my_谓词(列表1,Num_new);true)。
将_添加到_列表(列表2,列表1):-
发电机(L),
(\+memberchk(L,List2)->List1=[L | List2];List1=List2)。

也就是说,基本上,在每个递归循环中,List1(新列表)作为List2(旧列表)传递。

在我看来,这好像是在尝试命令式思维。你问题的背景是什么?(你试图在Prolog中做一些我认为不必要的事情。因此,我想,你头脑中有一个概念/假设,与Prolog的假设不同。通过告诉我们上下文,我们可以识别该假设,并用我们的思维方式澄清差异。)可能重复的感谢。我已经在上面进行了编辑,以提供上下文。我认为这需要更广泛的上下文来确定正确的Prolog解决方案。您是否试图在同一列表中多次调用
my_谓词
?如果您试图“一次完成”,那么您可以使用递归谓词,甚至可以使用setof(L,generate(L),ListOut)
来消除重复项。小注释:有一种变量可以更改,即不可回溯的存储。在您的回答中,应该会出现“unified”一词。:)是的,这是一条路。您可能需要将“Num\u new”定义为“succ(Num,Num\u new)”。