Lambda 在Prolog中分离由破折号分隔的原子名称

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]) :-

我需要分离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]) :- 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).