Lambda 在Prolog中分离由破折号分隔的原子名称
我需要分离a和b,然后构造两个新的函子,比如Lambda 在Prolog中分离由破折号分隔的原子名称,lambda,prolog,Lambda,Prolog,我需要分离a和b,然后构造两个新的函子,比如 functor([a1-b1,a2-b2,a3-b3,a4-b4]). 例如,您可以使用=..来构造和分解函子(请参阅)。要分解原子,可以使用统一: functora([a1,a2,a3,a4]), functorb([b1,b2,b3,b4]) 尽管我相信有更聪明的方法可以做到这一点。一般来说,SWI Prolog内置于atom操作中。这可能效率不高,但这是一个想法 sep_dash([A-B|Rest], [A|As], [B|Bs]) :-
functor([a1-b1,a2-b2,a3-b3,a4-b4]).
例如,您可以使用
=..
来构造和分解函子(请参阅)。要分解原子,可以使用统一:
functora([a1,a2,a3,a4]),
functorb([b1,b2,b3,b4])
尽管我相信有更聪明的方法可以做到这一点。一般来说,SWI Prolog内置于atom操作中。这可能效率不高,但这是一个想法
sep_dash([A-B|Rest], [A|As], [B|Bs]) :- sep_dash(Rest,As,Bs).
sep_dash([],[],[]).
我们可以在此基础上:
?- findall(A, member(A-B, [a1-b1,a2-b2,a3-b3,a4-b4]), As).
As = [a1, a2, a3, a4].
看起来它是有效的:
separate(Functor, Aside, Bside) :-
Functor =.. [Name, Arg],
findall(A, member(A-B, Arg), As),
findall(B, member(A-B, Arg), Bs),
atom_concat(Name, '_a', AFunctor),
atom_concat(Name, '_b', BFunctor),
Aside =.. [AFunctor, As],
Bside =.. [BFunctor, Bs].
不过,它只能在一个方向上工作
Edit您还可以通过使用上面的@Boris谓词来避免findall/3
的低效性:
?- separate(functor([a1-b1,a2-b2,a3-b3,a4-b4]), A, B).
A = functor_a([a1, a2, a3, a4]),
B = functor_b([b1, b2, b3, b4]).
使用此处找到的SWI Prolog和模块
lambda
,您可以编写:
separate(Functor, Aside, Bside) :-
Functor =.. [Name, Arg],
atom_concat(Name, '_a', AFunctor),
atom_concat(Name, '_b', BFunctor),
sep_dash(Arg, As, Bs),
Aside =.. [AFunctor, As],
Bside =.. [BFunctor, Bs].
library()具有所需的内置功能:
:- use_module(library(lambda)).
separate(In, Out1, Out2) :-
In =.. [_,L],
maplist(\X^Y^Z^(X = Y-Z), L, L1, L2),
Out1 =..[functora, L1],
Out2 =..[functorb, L2].
然后你可以重复使用A,B作为新函子的参数。我只是想说明破折号本身没有特殊意义,可以在统一中匹配。我个人可能会使用
sep_-dash(A-B,A,B)。
和maplist(sep_-dash,List,As,Bs)。
,或者甚至可能使用上面joel76所示的lambda库(尽管我个人并非在所有可能的情况下都喜欢lambdas)。我可能也会在实践中使用maplist。我喜欢findall/3
,因为它是内置的。太好了,我以前没有注意到这个。谢谢您可以通过部分应用程序将lambda的显式参数数量减少一个。@false我很好奇这会是什么样子。maplist(\Y^Z^X^(Y-Z=X),L1,L2,L)
可以简化为maplist(\Y^Z^=(Y-Z),L1,L2,L)
@false:您太快了,当我看到你的最后一条指令时,我正准备编辑我的答案。
?- pairs_keys_values([a1-b1,a2-b2,a3-b3,a4-b4],A,B).