Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Prolog谓词不工作_List_Prolog - Fatal编程技术网

List Prolog谓词不工作

List Prolog谓词不工作,list,prolog,List,Prolog,我完全搞不懂序言。我有两个简单的谓词,我正试图弄明白,但似乎不能得到正确的。首先,我试图找出delete谓词的一个变体,在这个变体中,我需要从List1中删除给定元素的所有引用,并查看它是否等于List2 这就是我试过的 del(S,[P],[P]). del(S,[S],[]). del(S,[H1,H2|T],L2) :- H1 = S, del([H2|T],L2). del(S,[H1,H2|T],[H1,T2]) :- H1 \= S, del([H2|T],T2). 另一个谓词获取

我完全搞不懂序言。我有两个简单的谓词,我正试图弄明白,但似乎不能得到正确的。首先,我试图找出delete谓词的一个变体,在这个变体中,我需要从List1中删除给定元素的所有引用,并查看它是否等于List2

这就是我试过的

del(S,[P],[P]).
del(S,[S],[]).
del(S,[H1,H2|T],L2) :- H1 = S, del([H2|T],L2).
del(S,[H1,H2|T],[H1,T2]) :- H1 \= S, del([H2|T],T2).
另一个谓词获取两个列表,获取List1中元素2的所有引用,并将其替换为4,然后查看List1是否与List2相同。要使其更简单,没有子列表

这些就是我尝试过的

change([],[]).
change([H1,H2|T],L) :- H1 = 2, append([2],L), change([H2|T],L).
change([H1,H2|T],L) :- H1 \= 2, append(H1,L), change([H2|T],L).

我想知道我犯了哪些错误,也许还想解释一下这些术语的工作原理。多谢各位

检查
del/3

(1) del(S,[P],[P]).
(2) del(S,[S],[]).
(3) del(S,[H1,H2|T],L2) :- H1 = S, del([H2|T],L2).
(4) del(S,[H1,H2|T],[H1,T2]) :- H1 \= S, del([H2|T],T2).
(1) change([],[]).
(2) change([H1,H2|T],L) :- H1 = 2, append([2],L), change([H2|T],L).
(3) change([H1,H2|T],L) :- H1 \= 2, append(H1,L), change([H2|T],L).
(1) 此规则表示列表
[p]
是删除元素
S
的列表
[p]
。该规则的问题在于
S
P
可能是相同的值,因此该规则并不总是正确的。如果您希望一直都是这样(这是一条有效的规则),则需要规定
S
P
不能实例化为相同的值:

del(S, [P], [P]) :- S \= P.
这是假设我们甚至需要这个规则,但我们暂时把它留在这里,因为在这个新的状态下,它是正确的

(2) 此规则表示
[]
是删除元素
S
的列表
[S]
。这是真的

(3) 这条规则说,如果
H1
S
是统一的,并且
L2
[H2 | T]
删除了
S
的,那么
L2
就是删除了
S
[H2 | T]
列表。但是,缺少一个论点。您有
del([H2 | T],L2)
,但是
del/3
被定义为包含3个参数。我们假设您的意思是
S
是第一个参数(
S
仍然是要删除的参数),因此
del(S,[H2 | T],L2)
。新修复的规则似乎符合逻辑

(4) 这条规则说,*
[H1,T2]
是列表
[H1,H2 | T]
,如果
H1
S
不一致,那么
T2
是列表
[H2 | T]
,元素
S
被删除。这与#3的问题相同,缺少
del/3
的参数,我们再次假设它是
S
,使其成为
del(S,[H2 | T],T2)
。另一个问题是您有
[H1,T2]
,这是一个只有两个元素的列表:
H1
T2
。又一个打字错误。这应该是
[H1 | T2]
。因此,修复后的规则现在似乎有意义了

仅仅修复这两个粗心的错误就可以使谓词几乎正常工作!实例化第一个参数时,它将生成正确的结果:

| ?- del(a, [a,b,c,a,d,a], L).

L = [b,c,d] ? a

no
此外,它可以被清理一点。
H2
在第3和第4条中没有真正使用。在第三个子句中,您可以在谓词的开头实例化
S
H1
。因此,这两个人成为:

(3) del(S, [S|T], L2) :- del(S, T, L2).
(4) del(S, [H|T], [H|T2]) :- H \= S, del(S, T, T2).
谓词在列表为空时失败。我不确定这是否是故意的,但您可以争辩说,
del(X,[],[])
应该是真的(当您从空列表中删除一个元素时,会产生一个空列表)。如果我们将此规则包括在内:

(1a) del(_, [], []).
我们现在可以去掉规则(1)和(2),因为(3)和(4)将处理它们并递归到规则(1a)

此外,在这种情况下,规则仍然无效:

| ?- del(X, [a,b,c], [a,c]).

no
如果这个打嗝就好了,
X=b
。问题在第(4)条中,我们检查
H\=S
,这意味着
H
S
是不可统一的。如果
S
是一个变量,则此表达式对我们不利,因为
H\=S
将始终失败(因为
S
确实可以统一为
H
)。因此,我们将其替换为dif(H,S),以检查这些术语是否相同。 有些序言不提供dif/2,在这种情况下,您可以用
\=
替代此解决方案(
H\==S
)。我们得到的规则集是:

(1) del(_, [], []).
(2) del(S, [S|T], L2) :- del(S, T, L2).
(3) del(S, [H|T], [H|T2]) :- dif(H, S), del(S, T, T2).
让我们“重读”这些规则:

  • 从空列表中删除的任何元素都是空列表
  • 移除元素
    S
    的列表
    [S|T]
    是列表
    L2
    ,如果
    L2
    是移除元素
    S
    的列表
    T
  • 如果
    S
    不同于
    H
    T2
    是移除元素
    S
    的列表
    T
    ,并且
    T2
    是移除元素
    S
    的列表
    T
  • 这看起来简单多了,尽管只需对原作进行几次简单的修改。现在它将产生这样的结果,这很好:

    | ?- del1(X, [a,b,c,b,d], [a,c,d]).
    
    X = b ? ;
    
    (1 ms) no
    

    检查
    变更/2

    (1) del(S,[P],[P]).
    (2) del(S,[S],[]).
    (3) del(S,[H1,H2|T],L2) :- H1 = S, del([H2|T],L2).
    (4) del(S,[H1,H2|T],[H1,T2]) :- H1 \= S, del([H2|T],T2).
    
    (1) change([],[]).
    (2) change([H1,H2|T],L) :- H1 = 2, append([2],L), change([H2|T],L).
    (3) change([H1,H2|T],L) :- H1 \= 2, append(H1,L), change([H2|T],L).
    
    (1) 这条规则说,如果我们更改空列表中的所有2,我们将得到空列表。听起来不错

    (2) 这条规则说,如果我取列表
    [H1,H2 | T]
    并将2改为4,如果
    H1
    为2,我将得到
    L
    ,并且我将
    L
    附加到
    [2]
    (这将在
    [2]之后一直失败)
    不是可变的-参见在线文档了解
    append/2
    append/3
    append/2
    用于附加列表,例如)和
    L
    [H2 | T]
    ,其中2改为4。这已经没有任何逻辑意义了。如果我要将2改为4,为什么要在
    [2]
    中添加内容?我们需要丢失
    追加
    ,只需将
    L
    [4 | T2]
    统一,其中
    T2
    [H2 | T]
    ,其2改为4。换句话说:

    (2) change([H1,H2|T], L) :- H1 = 2, L = [4|T2], change([H2|T], T2).
    
    这可以通过在上述条款的开头加入统一的方法进一步简化。同样要注意的是,在这里显示
    H2
    并没有实际用途。所以
    [
    
    (1) change([], []).
    (2) change([2|T], [4|T2]) :- change(T, T2).
    (3) change([H|T], [H|T2]) :- H \== 2, change(T, T2).
    
    exch(2, 4).
    exch(X, X) :-
       dif(X, 2).
    
    exch(A, B) :-
       (  A == 2 -> B = 4
       ;  A \= 2 -> A = B
       ;  A = 2, B = 4
       ;  A = B, dif(A,2)
       ).
    
    change(Xs, Ys) :-
       maplist(exch, Xs, Ys).
    
    change([], []).
    change([A|As], [B|Bs]) :-
       exch(A, B),
       change(As, Bs).
    
    ?- change([X],[Y]).
    X = 2,
    Y = 4 ;
    X = Y,
    dif(Y, 2).
    
    del(E, Xs, Ys) :-
       tfilter(dif_truth, Xs, Ys).
    
    dif_truth(X, Y, true) :-
       dif(X, Y).
    dif_truth(X, X, false).
    
    tfilter(     _, [], []).
    tfilter(CT, [E|Es], Fs0) :-
       call(CT,E,Truth),
       (  Truth = false,
          Fs0 = Fs
       ;  Truth = true,
          Fs0 = [E|Fs]
       ),
       tfilter(CT, Es, Fs).