在Prolog中分隔由短划线分隔的原子名称

时间:2013-03-22 18:18:59

标签: lambda prolog

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

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

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

4 个答案:

答案 0 :(得分:2)

使用SWI-Prolog和模块lambda http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl,你可以写:

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

答案 1 :(得分:1)

您可以使用例如=..来构建和拆分仿函数(请参阅here)。为了分解原子,你可以使用统一:

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

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

答案 2 :(得分: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]).

只能在一个方向上工作。

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

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

答案 3 :(得分:0)

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

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

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