Ł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
,我的谓词计算 MA
。 negate()
所做的是计算 ¬MA
而我希望它计算 M¬A
.
P.S。不要费心用 Predicate
的三值替换和 boolean
的三值替换来计算答案,因为我自己很清楚如何做到这一点。我问这个问题是为了找出纯 Java8 是否可以用最少的额外编码工作。
如果我们在 Predicate
class 中保留 negate()
的默认实现,就不可能做到这一点:默认情况下,这会构造一个始终 return 与初始谓词相反的布尔值。因此,不可能同时拥有 predicate.test(null)
和 predicate.negate().test(null)
return true
.
因此,我们需要实现自己的谓词。在以下实现中,使用 negate
布尔值维护状态。它为 trueValue
或 falseValue
指示 return 的正确值。对于 thirdValue
,true
总是 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());
}
};
}
有没有办法用 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
,我的谓词计算 MA
。 negate()
所做的是计算 ¬MA
而我希望它计算 M¬A
.
P.S。不要费心用 Predicate
的三值替换和 boolean
的三值替换来计算答案,因为我自己很清楚如何做到这一点。我问这个问题是为了找出纯 Java8 是否可以用最少的额外编码工作。
如果我们在 Predicate
class 中保留 negate()
的默认实现,就不可能做到这一点:默认情况下,这会构造一个始终 return 与初始谓词相反的布尔值。因此,不可能同时拥有 predicate.test(null)
和 predicate.negate().test(null)
return true
.
因此,我们需要实现自己的谓词。在以下实现中,使用 negate
布尔值维护状态。它为 trueValue
或 falseValue
指示 return 的正确值。对于 thirdValue
,true
总是 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());
}
};
}