规范化布尔表达式(使用Prolog)

时间:2014-12-16 20:34:49

标签: prolog

我无法规范化一系列逻辑谓词

假设我们有两个不重叠的时间段:

...... TA1 _____ TA2 ..... TB1 ______ TB2 ......

为了使时间段合法,不重叠并且有序a-> b,可以观察到以下事实:
ta1< TA2
tb1< TB2
ta1< TB1
ta1< TB2
ta2< = tb1
ta2< TB2

然而,很容易看出一个事实就足够了:
ta2< = tb1

是否存在将所有已知事实归一化为单一充分事实的数学结构?

最终我想在Prolog中编写那种推理,所以在这方面的任何指针都会很棒!

2 个答案:

答案 0 :(得分:0)

为了对此进行规范化,您需要一组小于(或相等)的元组以及一组您认为是假设的约束:应该保留的约束,但不需要检查。

这意味着输入应该是:

normalize([TA1<TA2,TB1<TB2,TA1<TB1,TA1<TB2,TA2<=TB1,TA2<TB2],[TA1<TA2,TB1<TB2,TA1<TB1],L).

首先规范不平等:

  • 如果A > B替换为B < A;和
  • 如果A >= B替换为B <= A

然后你可以做的是夸大这些假设:

  • 如果A<BB<C,则添加A<C;
  • 如果A<=BB<=C,则添加A<C;
  • 如果A<BB<C,则添加A<C;和
  • 如果A<=BB<=C,则添加A<=C

最后,从约束列表中删除已发现的关系。因此:

    如果给出A <= B,则
  • 删除A <= B;
  • 如果给出A <= B,则
  • 删除A < B;
  • 如果给出A < B,则
  • 删除A < B;和
  • 如果A <= B被提供,则
  • 替换A=B中的A < B

最后删除冗余约束:

  • A<BA<BA<B;
  • A<=BA<=BA<=B;
  • A<BA<=BA<B;和(来自@Patrick J. S.)
  • A<=BB<=AA=B

答案 1 :(得分:0)

以下是您可以使用SWI-Prolog和CHR执行的操作的示例:

:- use_module(library(chr)).

:- op(700,xfx,before).

:- chr_constraint before/2, t/2, clean/0.

% X before Y means variable X is less-or-equal to variable Y
% 
transitivity @ X before Y, Y before Z ==> X \= Y, Y \= Z | X before Z.
idempotence  @ X before Y \ X before Y <=> true.

irreflexivity @ t(N,_) before t(M, _), t(M,_) before t(N, _) <=> fail.

generation @ t(N,X) before t(M, M1) ==> member(X, [1,2]),
                                  member(Y, [1,2]),
                                  X \= Y,
                                  M \= N | t(N,Y) before t(M, M1).

generation @ t(N,N1) before t(M, X) ==> member(X, [1,2]),
                                  member(Y, [1,2]),
                                  X \= Y,
                                  M \= N | t(N,N1) before t(M, Y).

% if task N is before task M keep only relevant before
clean_1 @ t(N,N1) before t(M,M1) \ t(N,N2) before t(M,M2) <=> N2 < N1, M1 =< M2 | true.
clean_1 @ t(N,N1) before t(M,M1) \ t(N,N2) before t(M,M2) <=> N2 =< N1, M1 < M2 | true.

%if task N is before task M,  suppress unnecessary t(N, _) before t(N,_)
clean_2 @ t(N, _) before t(M,_)\ t(N, _) before t(N, _) <=> N \= M | true.

% if task N is before task M suppress unnecessary t(M, _) before t(M,_)
clean_3 @ t(N, _) before t(M,_)\ t(M, _) before t(M, _) <=> N \= M  | true.

% if tasks are chained, suppress unnecessary t(First,_) before t(Last,_)
clean_4 @ t(N,_) before t(M,_), t(M,_) before t(P,_) \ t(N,_)  before t(P,_) <=> N \= M, N \= P, M \= P
                                         | true.

% when program is finished clear the set of constraints
clean @ clean \ _ before _  <=> true.
clean @ true \ clean <=> true.


go :-
        % ta1 < ta2
    t(1,1) before t(1,2),
    % tb1 < tb2
    t(2,1) before t(2,2),
    % ta1 < tb1
    t(1,1) before t(2,1),
    % ta1 < tb2
    t(1,1) before t(2,2),
    % ta2 <= tb1
    t(1,2) before t(2,1),
    % ta2 < tb2
    t(1,2) before t(2,2),
    setof(X before Y, find_chr_constraint(X before Y) , Lt),
    writeln(Lt),
    clean.

你得到:

 ?- go.
[t(1,2)before t(2,1)]
true ;
false.