简体   繁体   English

Prolog递归方括号

[英]Prolog recursive square brackets

Given the code below, I am trying to call the last rule: trans([[p],[q],[r]]). 鉴于下面的代码,我试图调用最后一条规则: trans([[p],[q],[r]]).

This should then recursively call trans([P]), write, trans([P],[Q]]). 然后应该递归调用trans([P]), write, trans([P],[Q]]).

However it appears to be calling trans([P]), write, trans([P,Q]). 然而,它似乎是调用trans([P]), write, trans([P,Q]).

Is there a way to override the reserved square bracket? 有没有办法覆盖保留的方括号? Is there a better way to enable the recursion? 有没有更好的方法来启用递归?

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

Terminal Output: 终端输出:

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

Perhaps something like this. 也许这样的事情。 There's a bit of splitting out of clauses to make the parenthesis come out nice. 有一些分裂条款,使括号出来很好。

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

Some test results: 一些测试结果:

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

You query: 您查询:

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

gets instantiated with 获得实例化

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

(or: the 4th clause of trans/1 ). (或: trans/1的第4条)。 You want it to instantiate with 你希望它实例化

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

(or: the 10th clause of trans/1 ). (或: trans/1的第10条)。

The reason why this happens is that trans([[p],[q],[r]]) unifies with [P,Q,R] according to the following substitution: P = [p] , Q = [q] , and R = [r] . 发生这种情况的原因是trans([[p],[q],[r]])根据以下替换与[P,Q,R]结合: P = [p]Q = [q] ,并且R = [r]

Proper use of recursion 正确使用递归

Your code looks a little verbose for Prolog code. 对于Prolog代码,您的代码看起来有点冗长。 I therefore give a possible rewrite here that uses recursion proper. 因此,我在这里给出了一个可能正确使用递归的重写。

Instead of: 代替:

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

you can also write: 你也可以这样写:

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

... and that works for any list argument that is given to trans/1 . ...这适用于任何给trans/1列表参数。

Distinguish disjunction from conjunction 区分脱节与结合

You are not making the distinction between conjunction and disjunction correctly yet, you may want to try out: 你没有正确区分连接和分离,你可能想尝试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM