Prolog 算术拼图序言

Prolog 算术拼图序言,prolog,Prolog,我必须在列表中的数字之间加上+和-才能得到提供的数字。例如12-34=-22。我是这样做的: arit(L, Ls, S) :- arit(L, Ls, S, 0). arit([], [], R, R). arit([E|L], Ls, R, S) :- S1 is S + E, Ls = [+|[E|Ns]], arit(L, Ns, R, S1). arit([E|L], Ls, R, S) :- S1 is S - E, Ls = [

我必须在列表中的数字之间加上+和-才能得到提供的数字。例如12-34=-22。我是这样做的:

arit(L, Ls, S) :- arit(L, Ls, S, 0).
arit([], [], R, R).

arit([E|L], Ls, R, S) :- 
    S1 is S + E, 
    Ls = [+|[E|Ns]], 
    arit(L, Ns, R, S1).

arit([E|L], Ls, R, S) :- 
    S1 is S - E, 
    Ls = [-|[E|Ns]], 
    arit(L, Ns, R, S1).


arit([E|L], Ls, R, S) :- 
    S1 is (S*10 + E), 
    Ls=[E|Ns], 
    arit(L, Ns, R, S1).

它是有效的,但有重复的答案(比如1+2+3和+1+2+3)。也许有人有一个建议如何优化它?编辑这段代码根本不起作用,请查看答案。

事实上,您的代码没有正常工作。要确认此事实,请尝试以下查询:

?- put_arit2([1,2,3,4], L, 22).
false.
很容易检查,
[-,1,2,+,3,4]
将是正确的答案

因此,我建议以下解决方案(在SWI Prolog中):

  • 定义一个谓词,该谓词可以生成所有可能的列表(带有运算符)
  • 将每个可能的列表转换为相应的算术表达式,并检查它是否具有所需的值
示例:

?- putop([1,2,3,4], L, 22).
L = [-, 1, 2, +, 3, 4] ;
false.

?- putop([1,2,3,4,5,6,7,8,9], L, 4).
L = [+, 1, +, 2, -, 3, 4, +, 5, +, 6, +, 7, +, 8, +, 9] ;
L = [+, 1, 2, +, 3, -, 4, +, 5, -, 6, -, 7, -, 8, +, 9] ;
L = [+, 1, 2, +, 3, -, 4, -, 5, +, 6, -, 7, +, 8, -, 9] ;
L = [+, 1, 2, -, 3, +, 4, +, 5, -, 6, -, 7, +, 8, -, 9] ;
L = [+, 1, 2, -, 3, +, 4, -, 5, +, 6, +, 7, -, 8, -, 9] ;
L = [+, 1, 2, -, 3, +, 4, 5, -, 6, 7, +, 8, +, 9] ;
L = [+, 1, 2, -, 3, -, 4, -, 5, -, 6, -, 7, +, 8, +, 9] ;
L = [+, 1, 2, -, 3, 4, -, 5, 6, -, 7, +, 8, 9] ;
L = [-, 1, +, 2, +, 3, 4, +, 5, 6, -, 7, 8, -, 9] ;
L = [-, 1, +, 2, 3, +, 4, 5, +, 6, -, 7, 8, +, 9] ;
L = [-, 1, -, 2, +, 3, 4, -, 5, +, 6, 7, -, 8, 9] ;
L = [-, 1, -, 2, 3, -, 4, +, 5, 6, -, 7, -, 8, -, 9] ;
L = [-, 1, 2, +, 3, +, 4, +, 5, -, 6, -, 7, +, 8, +, 9] ;
L = [-, 1, 2, +, 3, +, 4, -, 5, +, 6, +, 7, -, 8, +, 9] ;
L = [-, 1, 2, +, 3, -, 4, +, 5, +, 6, +, 7, +, 8, -, 9] ;
L = [-, 1, 2, +, 3, -, 4, -, 5, -, 6, 7, +, 8, 9] ;
L = [-, 1, 2, -, 3, -, 4, +, 5, -, 6, +, 7, +, 8, +, 9] ;
L = [-, 1, 2, -, 3, 4, +, 5, 6, -, 7, -, 8, +, 9] ;
false.
[编辑]如果您不想使用内置谓词
原子列表\u concat/2
从原子/3
读取\u term\u,那么您需要创建自己的谓词来计算数字和运算符列表

putop(L, E, V) :-
     putop(L, E),
     evaluate(E, V).

putop([], []).
putop(L, [O|D]) :-
    member(O, [+,-]),
    append([X|A], B, L),
    append([X|A], C, D),
    putop(B, C).

evaluate(List, Value) :-
    evaluate(List, 0, Value).

evaluate([], Value, Value).
evaluate([Operator|List], Accumulator, Value) :-
    operand(List, 0, Operand, Rest),
    add(Operator, Accumulator, Operand, NewAccumulator),
    evaluate(Rest, NewAccumulator, Value).

operand([], Accumulator, Accumulator, []).
operand([+|Rest], Accumulator, Accumulator, [+|Rest]).
operand([-|Rest], Accumulator, Accumulator, [-|Rest]).
operand([Digit|Rest], Accumulator, Value, List) :-
    Digit \= +,
    Digit \= -,
    NewAccumulator is 10*Accumulator + Digit,
    operand(Rest, NewAccumulator, Value, List).

add(+, Accumulator, Operand, NewAccumulator) :-
    NewAccumulator is Accumulator + Operand.
add(-, Accumulator, Operand, NewAccumulator) :-
    NewAccumulator is Accumulator - Operand.

看看这个问题:不是完全相同的问题,但是相同的想法哦,是的,我没有检查负数和两个数字。。是的,你的解决方案很好,但我尝试在没有任何prolog谓词的情况下(原子列表等)实现它。所以我认为这会减少解决方案,但对于初学者来说,如果我只能在列表的第一个数字后面,第一个元素后面放一个符号会怎么样?也许你知道我该怎么做?我对prolog很陌生,所以困在这些基本任务上很糟糕。现在我用晨视仪检查了它,哦,天哪,我的解决方案很快就不起作用了。@LorusIndicus在我的回答中看到了“编辑”。是的,我今天提出了类似的解决方案,非常感谢你的帮助。
putop(L, E, V) :-
     putop(L, E),
     evaluate(E, V).

putop([], []).
putop(L, [O|D]) :-
    member(O, [+,-]),
    append([X|A], B, L),
    append([X|A], C, D),
    putop(B, C).

evaluate(List, Value) :-
    evaluate(List, 0, Value).

evaluate([], Value, Value).
evaluate([Operator|List], Accumulator, Value) :-
    operand(List, 0, Operand, Rest),
    add(Operator, Accumulator, Operand, NewAccumulator),
    evaluate(Rest, NewAccumulator, Value).

operand([], Accumulator, Accumulator, []).
operand([+|Rest], Accumulator, Accumulator, [+|Rest]).
operand([-|Rest], Accumulator, Accumulator, [-|Rest]).
operand([Digit|Rest], Accumulator, Value, List) :-
    Digit \= +,
    Digit \= -,
    NewAccumulator is 10*Accumulator + Digit,
    operand(Rest, NewAccumulator, Value, List).

add(+, Accumulator, Operand, NewAccumulator) :-
    NewAccumulator is Accumulator + Operand.
add(-, Accumulator, Operand, NewAccumulator) :-
    NewAccumulator is Accumulator - Operand.