Prolog为给定列表生成所有可能的操作

时间:2016-04-12 07:51:09

标签: list prolog operators combinations permutation

您好我遇到了问题。假设我有3个操作(+, - ,*)。 我想使用这3个运算符生成包含给定参数列表的所有可能表达式的变量。

my_problem([1,2],X)会返回

X=1-2
X=1*2
X=1+2

my_problem([1,2,3],X)会返回

X=1+2+3  X=1-2-3
X=1+2-3  X=1+2*3 
X=1-2+3  ...

等等。

我知道我可以使用这个谓词构建表达式。

args_expr(Arg1,Arg2,Arg1 + Arg2).
args_expr(Arg1,Arg2,Arg1 - Arg2).
args_expr(Arg1,Arg2,Arg1 * Arg2).

有没有聪明的方法来生成这个变量?我将不胜感激任何帮助或建议。

1 个答案:

答案 0 :(得分:1)

你可以使用所谓的" univ"运算符=..,用于构建表达式:

?- Expr =.. [+, A, B].
Expr = A+B.

您可以枚举您的操作:

op(+). op(-). op(*).

然后:

?- op(Op), Expr =.. [Op, A, B].
Op =  (+),
Expr = A+B ;
Op =  (-),
Expr = A-B ;
Op =  (*),
Expr = A*B.

或者也许:

?- op(Op1), op(Op2), E =.. [Op1, A, E0], E0 =.. [Op2, B, C].

从这里到你需要的只是弄清楚如何为任意数量的元素(不仅仅是两个或三个)列表。

提示:如果你弄清楚如何定义expr/3,你可以这样做:

?- foldl(expr, [B,C], A, E).
E = C+ (B+A) ;
E = C- (B+A) ;
E = C* (B+A) ;
E = C+ (B-A) ;
E = C- (B-A) ;
E = C* (B-A) ;
E = C+B*A ;
E = C-B*A ;
E = C* (B*A).

当然,foldl的第二个参数可以是任意长度的列表。