2
functor([a1-b1,a2-b2,a3-b3,a4-b4]).

我需要将 a 和 b 分开并构造新的两个仿函数,例如

functora([a1,a2,a3,a4]),
functorb([b1,b2,b3,b4])
4

4 回答 4

3

lambda使用此处http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl找到的 SWI-Prolog 和模块,您可以编写:

:- 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].
于 2013-03-22T20:57:01.913 回答
2

例如,您可以使用=..构造和分解仿函数(参见此处)。为了分解原子,您可以使用统一:

sep_dash([A-B|Rest], [A|As], [B|Bs]) :- sep_dash(Rest,As,Bs).
sep_dash([],[],[]).

虽然我确信有一些更聪明的方法可以做到这一点。通常,这些是用于原子操作的 SWI-Prolog 内置插件。

于 2013-03-22T18:34:54.577 回答
1

library( pairs ) 具有您需要的内置功能:

?- pairs_keys_values([a1-b1,a2-b2,a3-b3,a4-b4],A,B).

然后您可以重用 A,B 作为新仿函数的参数。

于 2013-03-22T21:06:32.587 回答
0

这可能不是非常有效,但这是一个想法。

?- 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].

看起来它有效:

?- 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]).

虽然只在一个方向上起作用。

编辑findall/3您还可以通过使用上面的@Boris 谓词来避免效率低下:

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].
于 2013-03-22T20:17:28.817 回答