在不使用maplist的情况下对列表中的所有成员(包括子列表Prolog)进行平方 [英] square all members in the list including sublist Prolog without using maplist
问题描述
我对Prolog并不陌生,他试图实现一种深平方谓词,该谓词对列表以及子列表中的所有数字求平方.我写了一些有效的代码,但没有给我期望的输出.
I am new to Prolog and trying to implement a sort of a deep square predicate, which squares all the numbers in the list and also in the sublists. I wrote some sort of a working code but its not giving me the output i expect.
代码:
dsquare([],S).
dsquare([H|T],[R|S]):- number(H), dsquare(T,S), R is H*H, !.
dsquare([H|T],S):- isList(H), dsquare(H,S).
dsquare([H|T],[R|S]) :- dsquare(T,S), R = H, !.
当前输出:
2?- dsquare([[2],4,a],X).
X = [4| _VDHV] ;
X = [[2], 16, a| _VDNM] ;
fail.
预期输出:
X = [[4],16,a]
X = [[4], 16, a]
我也想知道为什么我在输出中得到那些'_VDHV'和'_VDNM'. 任何帮助将不胜感激.
Also i wanted to know why am i getting those '_VDHV' and '_VDNM' in my output. Any help would be much appreciated.
好的,所以我将代码更新为:
ok so I updated my code as:
dsquare([],[]).
dsquare([H|T],[R|S]):- number(H), R is H*H, dsquare(T,S).
dsquare([H|T],[R|S]):- isList(H), dsquare(H,R), dsquare(T,S).
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S).
但是我得到的输出是:
13?- dsquare([a,3,[[2]],b,4],X).
X = [a, 9, [[4]], b, 16] ;
X = [a, 9, [[4]], b, 4] ;
X = [a, 9, [[2]], b, 16] ;
X = [a, 9, [[2]], b, 4] ;
X = [a, 9, [[2]], b, 16] ;
X = [a, 9, [[2]], b, 4] ;
X = [a, 9, [[2]], b, 16] ;
X = [a, 9, [[2]], b, 4] ;
X = [a, 3, [[4]], b, 16] ;
X = [a, 3, [[4]], b, 4] ;
X = [a, 3, [[2]], b, 16] ;
X = [a, 3, [[2]], b, 4] ;
X = [a, 3, [[2]], b, 16] ;
X = [a, 3, [[2]], b, 4] ;
X = [a, 3, [[2]], b, 16] ;
X = [a, 3, [[2]], b, 4] ;
fail.
我不知道它如何获得这么多结果.
I have no clue how it gets so many results.
编辑 最后可行的解决方案是
Edit finally the working solution is
dsquare([],[]).
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S).
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S).
dsquare([H|T],[H|S]) :- dsquare(T,S).
推荐答案
您的序言应该警告您有关第一规则和第三规则中的单个".
your Prolog should warn you about a 'singleton' in your first and third rules.
尝试
dsquare([],[]).
...
dsquare([H|T],[S|R]):- isList(H), dsquare(H,S), dsquare(T,R).
在没有动力原因的情况下,OT切勿裁切.
OT don't place cuts without a motivated reason.
edit 您会获得更多结果,因为最后一条规则在回溯时被触发了.现在可能是将剪切片段放置在需要的位置 的时候了(即在代码进入受条件保护的分支之后):
edit you get more results beacuse the last rule get fired on backtracking. Now could be the time to place the cuts where needed (i.e. after the code entered a branch guarded by a condition):
dsquare([],[]).
dsquare([H|T],[R|S]) :- number(H), !, R is H*H, dsquare(T,S).
dsquare([H|T],[R|S]) :- isList(H), !, dsquare(H,R), dsquare(T,S).
dsquare([H|T],[R|S]) :- R=H, dsquare(T,S).
或考虑考虑重复代码的重构:
or consider a refactoring that accounts for repeated code:
dsquare([],[]).
dsquare([H|T],[R|S]) :-
( number(H)
-> R is H*H
; isList(H)
-> dsquare(H,R)
; R=H
),
dsquare(T,S).
edit 上面的定义(我用'if/then/else'测试过)看起来不错:
edit the above definition (I tested that with 'if/then/else') seems fine:
1 ?- dsquare([[2],4,a],X).
X = [[4], 16, a].
2 ?- dsquare([a,[3],[[[5]]],[2],a],X).
X = [a, [9], [[[25]]], [4], a].
这篇关于在不使用maplist的情况下对列表中的所有成员(包括子列表Prolog)进行平方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!