kleene_value.rs (3577B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 //! Kleen logic: https://en.wikipedia.org/wiki/Three-valued_logic#Kleene_and_Priest_logics 6 7 /// A "trilean" value based on Kleen logic. 8 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 9 pub enum KleeneValue { 10 /// False 11 False = 0, 12 /// True 13 True = 1, 14 /// Either true or false, but we’re not sure which yet. 15 Unknown, 16 } 17 18 impl From<bool> for KleeneValue { 19 fn from(b: bool) -> Self { 20 if b { 21 Self::True 22 } else { 23 Self::False 24 } 25 } 26 } 27 28 impl KleeneValue { 29 /// Turns this Kleene value to a bool, taking the unknown value as an 30 /// argument. 31 pub fn to_bool(self, unknown: bool) -> bool { 32 match self { 33 Self::True => true, 34 Self::False => false, 35 Self::Unknown => unknown, 36 } 37 } 38 39 /// Return true if any result of f() is definitely true. 40 /// Otherwise, return the `or` of all values. 41 /// Returns false if empty, like that of `Iterator`. 42 #[inline(always)] 43 pub fn any<T>(iter: impl Iterator<Item = T>, f: impl FnMut(T) -> Self) -> Self { 44 Self::any_value(iter, Self::True, Self::False, |a, b| a | b, f) 45 } 46 47 /// Return false if any results of f() is definitely false. 48 /// Otherwise, return the `and` of all values. 49 /// Returns true if empty, opposite of `Iterator`. 50 #[inline(always)] 51 pub fn any_false<T>(iter: impl Iterator<Item = T>, f: impl FnMut(T) -> Self) -> Self { 52 Self::any_value(iter, Self::False, Self::True, |a, b| a & b, f) 53 } 54 55 #[inline(always)] 56 fn any_value<T>( 57 iter: impl Iterator<Item = T>, 58 value: Self, 59 on_empty: Self, 60 op: impl Fn(Self, Self) -> Self, 61 mut f: impl FnMut(T) -> Self, 62 ) -> Self { 63 let mut result = None; 64 for item in iter { 65 let r = f(item); 66 if r == value { 67 return r; 68 } 69 if let Some(v) = result.as_mut() { 70 *v = op(*v, r); 71 } else { 72 result = Some(r); 73 } 74 } 75 result.unwrap_or(on_empty) 76 } 77 } 78 79 impl std::ops::Not for KleeneValue { 80 type Output = Self; 81 82 fn not(self) -> Self { 83 match self { 84 Self::True => Self::False, 85 Self::False => Self::True, 86 Self::Unknown => Self::Unknown, 87 } 88 } 89 } 90 91 // Implements the logical and operation. 92 impl std::ops::BitAnd for KleeneValue { 93 type Output = Self; 94 95 fn bitand(self, other: Self) -> Self { 96 if self == Self::False || other == Self::False { 97 return Self::False; 98 } 99 if self == Self::Unknown || other == Self::Unknown { 100 return Self::Unknown; 101 } 102 Self::True 103 } 104 } 105 106 // Implements the logical or operation. 107 impl std::ops::BitOr for KleeneValue { 108 type Output = Self; 109 110 fn bitor(self, other: Self) -> Self { 111 if self == Self::True || other == Self::True { 112 return Self::True; 113 } 114 if self == Self::Unknown || other == Self::Unknown { 115 return Self::Unknown; 116 } 117 Self::False 118 } 119 } 120 121 impl std::ops::BitOrAssign for KleeneValue { 122 fn bitor_assign(&mut self, other: Self) { 123 *self = *self | other; 124 } 125 } 126 127 impl std::ops::BitAndAssign for KleeneValue { 128 fn bitand_assign(&mut self, other: Self) { 129 *self = *self & other; 130 } 131 }