Łukasiewicz 谓词逻辑?

Łukasiewicz predicate logic?

有没有办法用 Java API 来模拟 Łukasiewicz 的三值逻辑?

更具体地说,我想模仿 Łukasiewicz 的 'M' ("it is not false that...") 运算符。

例如,我需要构造这个 Predicate<String>,它给出以下结果:

predicate.test("0") = false
predicate.test(null) = true
predicate.test("1") = true

当取反时,给出:

predicate.negate().test("0") = true
predicate.negate().test(null) = true
predicate.negate().test("1") = false

如果要测试的值是 A,我的谓词计算 MAnegate() 所做的是计算 ¬MA 而我希望它计算 M¬A.

P.S。不要费心用 Predicate 的三值替换和 boolean 的三值替换来计算答案,因为我自己很清楚如何做到这一点。我问这个问题是为了找出纯 Java8 是否可以用最少的额外编码工作。

如果我们在 Predicate class 中保留 negate() 的默认实现,就不可能做到这一点:默认情况下,这会构造一个始终 return 与初始谓词相反的布尔值。因此,不可能同时拥有 predicate.test(null)predicate.negate().test(null) return true.

因此,我们需要实现自己的谓词。在以下实现中,使用 negate 布尔值维护状态。它为 trueValuefalseValue 指示 return 的正确值。对于 thirdValuetrue 总是 returned。如果使用既不是 3 个值之一的值测试谓词,则 false 总是 returned(您的问题中未提及这种情况,因此请随意调整)。

public static void main(String... args) {
    Predicate<String> predicate = lukasiewicz("1", "0", null);

    System.out.println(predicate.test("0"));
    System.out.println(predicate.test(null));
    System.out.println(predicate.test("1"));

    System.out.println(predicate.negate().test("0"));
    System.out.println(predicate.negate().test(null));
    System.out.println(predicate.negate().test("1"));
}

private static <T> Predicate<T> lukasiewicz(T trueValue, T falseValue, T thirdValue) {
    class LukasiewiczPredicate implements Predicate<T> {

        private boolean negate; 

        private LukasiewiczPredicate(boolean negate) {
            this.negate = negate;
        }

        @Override
        public boolean test(T t) {
            if (Objects.equals(trueValue, t)) return negate;
            if (Objects.equals(falseValue, t)) return !negate;
            if (Objects.equals(thirdValue, t)) return true;
            return false;
        }

        @Override
        public Predicate<T> negate() {
            return new LukasiewiczPredicate(!negate);
        }

    };
    return new LukasiewiczPredicate(true);
}

看来这就是你想要的:

static <T> Predicate<T> p(Predicate<? super T> o){ //(I'm not sure what to name this)
    return new Predicate<T>(){
        @Override
        public boolean test(T t) {
            return t == null || o.test(t);
        }
        @Override
        public Predicate<T> negate(){
            return p(o.negate());
        }
    };
}
....
Predicate<String> predicate = p(t -> !"0".equals(t));

如果要测试的值为 null,我们 return 为真,否则我们使用原始谓词。要否定我们只是否定原始谓词。


如果 null 并不总是第三个值,您可以传入另一个谓词来测试它:

static <T> Predicate<T> p(Predicate<? super T> isUnknown, Predicate<? super T> isTrue){
    return new Predicate<T>(){
        @Override
        public boolean test(T t) {
            return isUnknown.test(t) || isTrue.test(t);
        }
        @Override
        public Predicate<T> negate(){
            return p(isUnknown, isTrue.negate());
        }
    };
}