(Addition) Habo we have used two-value logic in your application: non-TRUE is False. The calculation system of two-value logic is quite mature, or, or, non-derived, and non-oriented. But in practical applications, we will have a chance to encounter trial logic.
Three-value logic usually contains optional True, False, Null. How to join this NULL in a complete two-value logic arithmetic system, make it satisfied, and will not trigger logical contradictions, that is, we have to discuss here.
NULL is actually different algorithms when participating in logical operations. According to the "priority" of the NULL value in the calculation.
Usually we use the three-value logic used in the database, follow the principles of NULL. When there is a NULL value to participate in the binary operation, the return result is NULL, and the other is the same as the binary logic. This principle is based on the relational database as a "nil". Due to its meaningless, any logical value is inconsistent with the results of the operation, which is also consistent with the processing of NULL with many data-related databases.
On the other hand, some friends may not notice that the common permission system is also a three-value logic. The null value in this system is at the lowest priority. When the two rations are merged, FALSE is higher than everything. When there is no negation value, the affirmation value is higher than NULL, and only two values are NULL, the result is NULL. In fact, we can think of it as a three-value and computing, so it is easy to construct a corresponding logic or calculation for mathematical symmetry. This rule rule regards NULL is "unrefine".
The last specified NULL value is between TRUE and FALSE, and the operation, when the two has a false, return false, otherwise, when there is a NULL, return null, both of which return true; Or the operation, the two returns true when True, otherwise there is a NULL back to NULL, both of which return false when FALSE. This is equal to the respective priority of True and False or with the calculation. It is based on the concept of NULL value "unknown". Under this rule, the NULL value is strictly considered as unknown TRUE or FALSE (Unknown). There are also some databases of the three-value logic based on this system, and a DBBOOL example of this rule is given in the MSDN.
The academic discussion about NULL values has not been restless, and there is still a four-dimensional logic during this period. Practice also proves that there is more than one three-value logical system in the "true" world. In practice, the most suitable rule should be selected according to the specific situation.
I don't want to hide, when I write this chapter, I am proud of my heart. For true masters, those who have created powerful virtual machines, frames, and elegant libraries, MultiBoolean is really nothing. However, this is the first piece that can make myself satisfied. Although this design can't make perfect, it can meet the application needs of my current multi-value logic.
For a long time, what is the biggest problem that plasmunicates me is how different null values are compatible in multi-valued logic. Of course, from mathematical sense, different null values represent different logical spaces, and there should be no crossings between them. So the ideal state should be different logic according to some mark, and separate them separately. However, in a practical, a multi-value logic type that can handle multiple null logic without affecting the respective logical algorithms, and does not cause an exception, it seems more perfect. After all, it is a basic type, you should use as simple as possible - my blog records another multi-valued logic implementation, in practical, I feel that it is indeed too complicated. A logical type of only a few states actually requires the factory method to construct ... The direct cause of this complex structure is tried to express logic three states with -1, 0, 1. Maybe for a certain logic, this is suitable, but if you want to express multiple logical null values with a 0, it is too demanding.
Expressed with multiple integers? I have thought about this way, such as setting NIL to the minimum, Unknown is set to the maximum. However, it is difficult to achieve a simple and elegant algorithm to be compatible with these values. Original Unknown itself is very simple and beautiful, and other two other kinds are not intuitive, but it is enough to negotiate. When you put them together, you should not have any conflicts.
In an accidental opportunity, I think of a plural. Yes, the plural is exactly the form of expression I need! If the effective logical value is expressed as a real number, the null value is expressed as imaginary, which is the effect I need. In the form, due to the meaning of unknown, it can be considered as "real null value" or "possible logic value" system, that is, it is the origin of the active shaft intersection. --0. This is also compatible with the null algorithm in the MSDN.
This is an exciting discovery. Soon, I started looking for a suitable complex. Since the built-in complex type is not provided in the .NET CLR, I refer to the plural implementation of the complex in STL to write a C # version of the Complex type. The following things are how to make this idea.
The following is to implement code, in the document comment of the code, there is a detailed introduction of each main function:
Using system;
Using system.data;
USING MARCH.MATH;
Namespace march.vboolean
{
///
/// MultiBoolean is a final joined in the VBOOLAN namespace
///> The structure may also be the final type of multi-value discrete logic. compared to
/// Varboolean and Boolw3 in the same space, it is unified in mathematics three empty
/// Value rule, becoming a complete utility data type. The two will only be used in the future
/// is backward compatible, and these two types may be removed in later versions.
/// summary>
Public struct multiboolean
{
PRIVATE COMPLEX __VALUE;
Private static readonly complex truevalue = new complex (1, 0);
Private static readonly complex falsevalue = new complex (-1, 0);
Private static readonly complex unknownValue = new complex (0, 0);
Private static readonly complex undefinevalue = new complex (0, 1);
Private static readonly complex nilvalue = new complex (0, -1); ///
/// true value
/// summary>
Public Static Readonly Multiboolean true = new multiboolean (New Complex (1, 0));
///
/ // 假 假
/// summary>
Public Static Readonly MultiBoolean False = New MultiBoolean (New Complex (-1, 0));
///
/// MultiBoolean supports one of the null value types, indicating that this value is true or false
One of ///, but cannot be determined.
/// summary>
Public Static Readonly MultiBoolean unknown = new multiboolean (new complex (0, 0));
///
/// MultiBoolean supports one of the null value types, indicating undefined logical values.
/// If the Logic status is one of true, false, undefine, then the operation is permission
/// The permission check operation in the system.
/// summary>
Public Static Readonly Multiboolean undefine = New MultiBoolean (New Complex (0, 1));
///
///Riboolean supports one of the null value types, indicating meaningless logic values.
/// summary>
Public Static Readonly Multiboolean nil = new multiboolean (new complex (0, -1));
///
/// MultiBoolean inside the logic status in multiplexes, through this internal
/// Constructor Generates the logical value of the specified state.
/// summary>
/// Represents the complex value of the status, may value 1, -1, i, -i, 0 param>
Private MultiBoolean (Complex Value)
{
This .__ value = value;
}
Public Bool Istrue {get {return __value == trueValue;}}
Public bool isfalse {get {return __value == falsevalue;}}
Public Bool Isunknown {get {return __value == unknownValue;}}
Public bool isundefine {get {return __value == undefinevalue;}}
Public Bool Isnil {Get {Return__value == NilValue;}}
///
/// Two-value logic to the implicit transformation function of the MultiBoolean transformation.
/// Because multiple optional null values are defined in MultiBoolean, the CLR DBNULL is not defined.
/ / / The transition rule with binary logic, so it does not define the implicit /// conversion of DBNULL to MultiBoolean. Users who need to convert themselves can define their own type conversion according to their own application logic.
/// summary>
/// Logic value param>
///
Public static implicit operator multiboolean (BOOL X)
{
RETURN X? TRUE: FALSE;
}
///
/// MultiBoolean's operation.
/// Return value Press NIL, FALSE, UnkNown, True, and undefine priorities to take one of the two values.
/// If the logic status is one of true, false, undefine, then the association is the permission tube
/// The permission check operation in the system.
/// summary>
/// Left value param>
/// Right value param>
///
Public Static Multiboolean Operator & (MultiBoolean X, MultiBoolean Y)
{
IF (x.isnil || y.isnil)
Return NIL;
IF (x.isundefine)
Return Y;
IF (Y.Isundefine)
Return X;
Return New MultiBoolean (x .__ value.real } /// /// MultiBoolean or operation. /// Return value Press NIL, TRUE, UNKNOWN, FALSE, and UNDEFINE priority to take one of the two values. /// summary> /// Left value param> /// Right value param> /// Public Static MultiBoolean Operator | (MultiBoolean X, MultiBoolean Y) { IF (x.isnil || y.isnil) Return NIL; IF (x.isundefine) Return New MultiBoolean (y .__ value); IF (Y.Isundefine) Return New MultiBoolean (x .__ value); Return New MultiBoolean (x .__ value.real> y .__ value.real? x .__ value: y .__ value); } /// /// MultiBoolean's non-operation. TRUE and FALSE are non-valued. /// Non-operating non-operation is usually meaningless, still returning to the null value itself. Only /// X When True or False, this /// rule is also met when X == NIL, but its behavior is not different from T / F value). /// summary> /// Operation param> /// Public Static MultiBoolean Operator! (MultiBoolean X) { Return New MultiBoolean (New Complex (-x .__ value.real, x .__ value.imag); } /// /// MultiBoolean object's equivalent judgment, it is necessary to point out, for empty /// Value, determine if it does not have meaning, so there is at least one of the two values, /// Judgment according to the following rules: /// Only one is null value, returns the null state; /// When both are null, return a higher priority. /// Defining such a rule is just to facilitate the most common three-value logic applications, I don't think there should be no different null values. The occasion of comparison between ///, at least such an operation is very rare, and its mathematical significance is also blurred. // / When you need to define a rule such as your own judgment, you can call an instance method of the object Equals or static methods equals. /// summary> /// Left value param> /// Right value param> /// Public static multiboolean operator == (MultiBoolean X, MultiBoolean Y) { IF (x .__ value.real == 0 && y .__ value.Real == 0) Return New MultiBoolean (New Complex (0, System.math.min (x .__ value.imag, y .__ value.imag)); IF (x .__ value.real == 0 && y .__ value.real! = 0) Return New MultiBoolean (x .__ value); IF (x .__ value.real! = 0 && y .__ value.real == 0) Return New MultiBoolean (y .__ value); Return X.__ value.real == y .__ value.real? true: false; } /// The inequality of /// MultiBoolean object, it is necessary to point out, for empty /// Value, determine if it does not have meaning, so there is at least one of the two values, /// Judgment according to the following rules: /// Only one is null value, returns the null state; /// When both are null, return a higher priority. /// Defining such a rule is just to facilitate the most common three-value logic applications, I don't think there should be no different null values. The occasion of comparison between ///, at least such an operation is very rare, and its mathematical significance is also blurred. // / When you need to define a rule such as your own judgment, you can call an instance method of the object Equals or static methods equals. /// summary> /// Left value param> /// Right value param> /// Public Static MultiBoolean Operator! = (MultiBoolean X, MultiBoolean Y) { IF (x .__ value.real == 0 && y .__ value.Real == 0) Return New MultiBoolean (New Complex (0, System.math.min (x .__ value.imag, y .__ value.imag)); IF (x .__ value.real == 0 && y .__ value.real! = 0) Return New MultiBoolean (x .__ value); IF (x .__ value.real! = 0 && y .__ value.real == 0) Return New MultiBoolean (y .__ value); Return x .__ value.real == y .__ value.real? false: true; } /// /// Different or calculation, here, press X ^ Y = (! X & Y) rules, and only when X and Y are True / false ///, the expression is the same as! = Behavior. /// summary> /// Left value param> /// Right value param> /// Public Static MultiBoolean Operator ^ (MultiBoolean X, MultiBoolean Y) { Return (! x & y) | (x &! y); } Public Static Bool Operator True (MultiBoolean X) { Return x .__ value.real == 1; } Public Static Bool Operator False (MultiBoolean X) { Return x .__ value.real == -1; } /// ///RiBoolean object's equivalent state judgment, it is necessary to point out, for empty /// value, determine if it is equal, here is it just judging if the two objects are the same /// "Status", and they are not necessarily "equal" in mathematical sense. /// This method is to overreload system.object.equals (System.Object Obj) /// The general interface of the method. /// summary> /// Operation param> /// Public Override Bool Equals (Object Obj) { IF (Obj.gettype ()! = this.gettype ()) Return False; Return this.equals ((MultiBoolean) OBJ); } /// ///RiBoolean object's equivalent state judgment, it is necessary to point out, for empty /// value, determine if it is equal, here is it just judging if the two objects are the same /// "Status", and they are not necessarily "equal" in mathematical sense. /// summary> /// Operation param> /// Public Bool Equals (MultiBoolean X) { Return this .__ value == x .__ value; } /// ///RiBoolean object's equivalent state judgment, it is necessary to point out, for empty /// value, determine if it is equal, here is it just judging if the two objects are the same /// "Status", and they are not necessarily "equal" in mathematical sense. This static method is // This is different from the rules of the == operator for the user-defined logical system. /// summary> /// Left value param> /// Right value param> /// Public Static Bool Equals (MultiBoolean X, MultiBoolean Y) { Return X.__ value == y .__ value; } /// /// Get the Hash value, has been overloaded /// summary> /// Public Override Int getHashcode () { Return this .__ value.gethashcode (); } /// /// Express the MultiBoolean object as a corresponding string. /// summary> /// Public override string toString () { IF (this .__ value == TrueValue) Return "True"; IF (this .__ value == falsevalue) Return "false"; IF (this .__ value == undefinevalue) Return "Undefine"; IF (this .__ value == nilvalue) Return "NIL"; Return "unknown"; } /// /// Resolve the string to the corresponding multiboolean value. /// summary> /// The string value to be parsed is "True", "False", "Unknown", "undefine," nil ". param> /// < Returns> Corresponding multiboolean values. returns> Public Static MultiBoolean Parse (String Input) { Switch (Input) { Case "True": Return True; Case "false": Return False; Case "unknown": Return unknown; Case "undefine": Return Undefine; Case "NIL": Return NIL; DEFAULT: Throw new ArgumentException ("The String ISN't A Available Value.", INPUT; } } /// /// Remove the logical value from the database field value, and will be converted to MultiBoolean, and the value corresponding to DBNULL depends on /// User incoming ISNULL variable /// summary> /// The GetValue method of the database interface is usually an Object, which may be true, false, dbnull param> /// DBNULL corresponds to the value param> /// Public Static Multiboolean ReadDbvalue (Object Dbvalue, MultiBoolean Isnull) { IF (DBValue IS BOOL) RETURN (BOOL) DBVALUE? TRUE: FALSE; IF (DBVALUE IS DBNULL) Return isnull; Throw new ArgumentException ("Enter parameter is not a valid logic value", "dbvalue"); } /// /// Package the current object to T / f / dbnull /// Triple object, used to access database access interface /// value, this process will lose null state, /// With its non-insulting operation with ReadDbValue. /// summary> /// Public Object TodbojBect () { Switch (convert.toint32 (this .__ value.real)) { Case 1: Return (Object) True; Case -1: Return (Object) False; DEFAULT: Return DBNULL.VALUE; } } } }