Prolog递归方括号

时间:2014-05-01 12:23:03

标签: recursion prolog

鉴于以下代码,我试图调用最后一条规则:trans([[p],[q],[r]]).

然后应该递归调用trans([P]), write, trans([P],[Q]]).

但似乎是在调用trans([P]), write, trans([P,Q]).

有没有办法覆盖保留的方括号?有没有更好的方法来启用递归?

trans([P]) :- atom(P), write(P).
trans([~P]) :- write('Not '), trans([P]).

trans([P,Q]) :- trans(P), write(' or '), trans(Q).
trans([P,Q,R]) :- trans([P]), write(' or '), trans([Q,R]).
trans([P,Q,R,S]) :- trans([P]), write(' or '), trans([Q,R,S]).


trans([[P],[Q]]) :- trans([P]), write(' and '), trans([Q]).
trans([[P,Q],[R]]) :- trans([P,Q]), write(' and '), trans([R]).
trans([[P],[Q,R]]) :- trans([P]), write(' and '), trans([Q,R]).
trans([[P,Q],[R,S]]) :- trans([P,Q]), write(' and '), trans([R,S]).

trans([[P],[Q],[R]]) :- trans([P]), write(' and '), trans([[Q],[R]]).

终端输出:

?- trans([[p],[q],[r]]).
p and q or r
true ;
q and r
true .

2 个答案:

答案 0 :(得分:2)

也许是这样的。有一些分裂的条款使括号变得很好。

% Handle the top, conjunction level

trans([H]) :-                  % A single atomic conjunctive term
    atom(H), write(H).
trans([H]) :-                  % A single non-atomic conjunctive term
    trans_dis(H).
trans([H1,H2|T]) :-            % Multiple conjunctive terms
    trans_conj([H1,H2|T]).

trans_conj([H1,H2|T]) :-       % Multiple conjunctive terms
    trans_conj([H1]), write(' and '), trans_conj([H2|T]).
trans_conj([H]) :-             % Single atomic conjunctive term
    atom(H), write(H).
trans_conj([[H]]) :-           % Last conjunctive term, single disjunction
    trans_dis([H]).
trans_conj([[H1,H2|T]]) :-     % Last conjunctive term, multiple disjunctions
    write('('), trans_dis([H1,H2|T]), write(')').

% Handle the disjunctions level

trans_dis([H]) :-              % Single disjunctive term
    atom(H), write(H).
trans_dis([~H]) :-             % Single negated disjunctive term
    atom(H), write('not '), write(H).
trans_dis([H1,H2|T]) :-        % Multiple disjunctive terms
    trans_dis([H1]), write(' or '), trans_dis([H2|T]).

一些测试结果:

| ?- trans([p]).
p

true ? a

no
| ?- trans([[p]]).
p

true ? a

no
| ?-  trans([p,q]).
p and q

true ? a

no
| ?-  trans([[p,q]]).
p or q

true ? a

no
| ?-  trans([[p],[q]]).
p and q

true ? a

no
| ?- trans([[p,r],[q]]).
(p or r) and q

true ? a

no
| ?- trans([[p,r],[q,s]]).
(p or r) and (q or s)

| ?- trans([[a,~b,c],[d,e],[f]]).
(a or not b or c) and (d or e) and f

true ? a

(1 ms) no

答案 1 :(得分:0)

您查询:

?- trans([[p],[q],[r]]).

使用

进行实例化
trans([P,Q,R]) :- trans([P]), write(' or '), trans([Q,R]).

(或:trans/1的第4条)。你希望它用

实例化
trans([[P],[Q],[R]]) :- trans([P]), write(' and '), trans([[Q],[R]]).

(或:trans/1的第10条)。

发生这种情况的原因是trans([[p],[q],[r]])根据以下替换与[P,Q,R]统一:P = [p]Q = [q]R = [r]

正确使用递归

对于Prolog代码,您的代码看起来有点冗长。因此,我在这里给出了一个可能正确使用递归的重写。

而不是:

trans([P,Q]) :- trans(P), write(' or '), trans(Q).
trans([P,Q,R]) :- trans([P]), write(' or '), trans([Q,R]).
trans([P,Q,R,S]) :- trans([P]), write(' or '), trans([Q,R,S]).

你也可以写:

trans([]).
trans([H|T]):-
  trans(H),
  trans(T).

...并且适用于trans/1的任何列表参数。

区分分离与结合

你没有正确区分连词和分离,你可能想试试:

trans(and([]).
trans(and([H])):-
  trans(H).
trans(and([H|T])):-
  trans(H),
  write(' and '),
  trans(and(T)).

trans(or([])).
trans(or([H])):-
  trans(H).
trans(or([H|T])):-
  trans(P),
  write(' or '),
  trans(or(T)).