分享
 
 
 

March Library中的Multiboolean——多值逻辑实现

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

(附前文)习惯上我们在应用系统中一直使用两值逻辑:非True即False。两值逻辑的运算体系已经相当成熟,与、或、非以及衍生的异或、与非等等。但是在实际应用中,我们会有机会遇到三值逻辑。三值逻辑通常包含可选的True、False、NULL。如何在完备的两值逻辑运算体系中加入这个NULL,使之满足我们的需要,并且不会引发逻辑矛盾,就是我们要在这里讨论的。

NULL参与逻辑运算时,实际上存在着不同的算法。按NULL值在运算中的“优先级”分为三种。

通常我们在数据库中使用的三值逻辑,遵循NULL最优的原则。有NULL值参与二值运算时,返回结果为NULL,其它与二值逻辑相同。这一原则基于关系型数据库将NULL视为“无意义(Nil)”。由于其内容无意义,则任何逻辑值与之进行运算的结果都是无意义值,这也与许多数据关系型数据库对NULL的处理一致。

另一方面,可能有些朋友没有注意到,事实上常见的权限体系也是一种三值逻辑,这个体系里NULL值处于最低优先级,两个权限值进行合并时,False(否定)高于一切,没有否定值时,肯定值(True)高于NULL,只有两个值均为NULL时,结果才为NULL。实际上我们可以将它看作是一个三值与运算,那么出于数学上的对称,很容易可以构造出对应的逻辑或运算。这种运算规则视NULL为“未赋值(Undefine)”。

最后一种规定NULL值的优先级介于True和False之间,与运算,二者有一为False时,返回False,否则二者有一为NULL时,返回NULL,二者均为True时返回True;或运算,二者有一为True时返回True,否则二者有一为NULL时返回NULL,二者均为False时返回False。这等于分别承认True和False在或和与运算中的最高优先级。它基于NULL值为“未知”的理念。这种规则下,对NULL值严格视为未知的True或False(Unknown)。也有一些数据库的三值逻辑是基于这个体系的,MSDN中给出了一个基于此规则的DBBool示例。

关于NULL值的学术讨论其实一直没有休止过,这期间还出现过四元逻辑等理论。实践也证明,“真实”世界中客观存在着不止一种三值逻辑体系。在实用中应当依据具体情况选择最适合的规则。

我不想隐瞒,写下这一章的时候,我心里很自豪。对于真正的高手,那些创造了强大的虚拟机、框架和优雅类库的大师来讲,MultiBoolean这样的小东西确实不算什么。但是,这确是第一个可以让我自己满意的作品。虽然这个设计还不能作到完美,但是它已经可以满足我当前对多值逻辑的应用需求。

长期以来,困扰我的最大问题莫过于多值逻辑中不同的空值如何兼容。当然,从数学意义来讲,不同的空值代表了不同的逻辑空间,它们之间不应该存在交叉。所以理想状态应该是根据某种标记来区分不同的逻辑,并将它们分隔开。但是在实用中,一个可以在不影响各自的逻辑算法、不引发异常的前提下处理多种空值逻辑的多值逻辑类型,似乎更为完美。毕竟它是一个基础类型,应该使用尽可能简单——我的Blog上记载了另一种多值逻辑实现,在实用中,我感觉它确实过于复杂了。一个只有几种状态的逻辑类型,居然需要工厂方法来构造……

引起这种复杂结构的直接原因,即是我一直试图用-1,0,1三个整型来表达逻辑三态。也许对于某一种逻辑来讲,这样作是合适的,但是如果想要用一个0来表达多个逻辑空值,未免太过苛求了。

用多个整数来表达?这种方式我也想过,比如将Nil设为最小值,UnKnown设为最大值。然而很难实现一个简单优雅的算法来兼容这些值,本来UnKnown本身的算法很简洁漂亮,而其它另两种虽然不够直观,但是足以内洽。当把它们放在一起的时候,不应该产生任何冲突。

在一个偶然的机会,我想到了复数。是的,复数正是我需要的表达形式!如果将有效逻辑值表达为实数,将空值表达为虚数,这正是我所需要的效果。在形式上,由于Unknown的含义,恰恰可以将它视为“真正的空值”或“可能的逻辑值”两种体系的一个交叉点,也就是说,它正是那个实虚轴交叉的原点——0。而这也与MSDN中的空值算法兼容。

这是一个令我激动的发现。很快,我着手寻找合适的复数实现。由于.net CLR中没有提供内置的复数类型,我参考STL中的复数实现编写了一个C#版本的Complex类型。后面的事,就是怎样把这个想法具体化了。

以下就是实现代码,在代码的文档注释中,有各个主要功能的详细介绍:

using System;

using System.Data;

using March.Math;

namespace March.VBoolean

{

/// <summary>

/// MultiBoolean 是 VBoolean命名空间中最后加入的一个成

/// 员,从结构来讲,可能也是多值离散逻辑的最终类型了。相比

/// 同一空间内的VarBoolean和Boolw3,它在数学上统一了三种空

/// 值规则,成为一个完备实用的数据类型。后两者今后将只作为

/// 向下兼容而存在,并且在以后的版本中可能会去掉这两个类型。

/// </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);

/// <summary>

/// 真值

/// </summary>

public static readonly MultiBoolean True = new MultiBoolean(new Complex(1, 0));

/// <summary>

/// 假值

/// </summary>

public static readonly MultiBoolean False = new MultiBoolean(new Complex(-1, 0));

/// <summary>

/// MultiBoolean 支持的空值类型之一,表示该值是真或假中

/// 的一种,但是不能确定。

/// </summary>

public static readonly MultiBoolean Unknown = new MultiBoolean(new Complex(0, 0));

/// <summary>

/// MultiBoolean 支持的空值类型之一,表示未定义的逻辑值。

/// 如果限定逻辑状态为True,False,Undefine中的一种,那么与运算即为权限管

/// 理体系中的权限校验操作。

/// </summary>

public static readonly MultiBoolean Undefine = new MultiBoolean(new Complex(0, 1));

/// <summary>

/// MultiBoolean 支持的空值类型之一,表示无意义的逻辑值。

/// </summary>

public static readonly MultiBoolean Nil = new MultiBoolean(new Complex(0, -1));

/// <summary>

/// MultiBoolean 内部以复数表示逻辑状态,通过这个内部的

/// 构造函数生成指定状态的逻辑值。

/// </summary>

/// <param name='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;}}

/// <summary>

/// 两值逻辑向 MultiBoolean 转型的隐式转型函数。

/// 因为 MultiBoolean 中定义了多种可选的空值,CLR 的 DBNull并未定义

/// 与二值逻辑的转型规则,所以在这里不定义DBNull向 MultiBoolean 的隐式

/// 转换。需要进行转换的用户可以根据自己的应用逻辑定义自己的类型转换。

/// </summary>

/// <param name='x'>逻辑值</param>

/// <returns>转换后的 MultiBoolean </returns>

public static implicit operator MultiBoolean(bool x)

{

return x? True: False;

}

/// <summary>

/// MultiBoolean的与操作。

/// 返回值按Nil, False,Unknown,True, UnDefine 的优先级从两值中取一返回。

/// 如果限定逻辑状态为True,False,Undefine中的一种,那么该与运算即为权限管

/// 理体系中的权限校验操作。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

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 < y.__value.real ? x.__value : y.__value);

}

/// <summary>

/// MultiBoolean的或操作。

/// 返回值按Nil, True,Unknown,False, UnDefine 的优先级从两值中取一返回。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

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);

}

/// <summary>

/// MultiBoolean的非操作。True和False互为非值。

/// 空值的非操作通常没有意义,仍返回空值本身。当且仅当

/// x为True或False时,!x=x&False(实际上x==Nil时也满足这个

/// 规则,但其行为与T/F值的非不相同)。

/// </summary>

/// <param name='x'>操作数</param>

/// <returns>返回值</returns>

public static MultiBoolean operator ! (MultiBoolean x)

{

return new MultiBoolean(new Complex(-x.__value.real, x.__value.imag));

}

/// <summary>

/// MultiBoolean 对象的等值判断,需要指出的是,对于空

/// 值,判断其是否相等没有意义,故两值中有至少一个为空时,

/// 按以下规则判断:

/// 只有一个为空值时,返回该空值状态;

/// 两个都为空值时,返回优先级较高的一个。

/// 定义这样的规则只是为了方便最常见的三值逻辑应用,我认为不应该出现不同空值

/// 之间发生比较的场合,至少这样的运算非常罕见,而它的数学意义也模糊不清。

/// 需要定义自己的判等规则时,可以调用对象的实例方法Equals或静态方法Equals。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

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;

}

/// <summary>

/// MultiBoolean 对象的不等判断,需要指出的是,对于空

/// 值,判断其是否相等没有意义,故两值中有至少一个为空时,

/// 按以下规则判断:

/// 只有一个为空值时,返回该空值状态;

/// 两个都为空值时,返回优先级较高的一个。

/// 定义这样的规则只是为了方便最常见的三值逻辑应用,我认为不应该出现不同空值

/// 之间发生比较的场合,至少这样的运算非常罕见,而它的数学意义也模糊不清。

/// 需要定义自己的判等规则时,可以调用对象的实例方法Equals或静态方法Equals。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

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;

}

/// <summary>

/// 异或运算,这里按x^y=(!x&y)|(x&!y)规则,当且仅当x和y为True/False中一个

/// 时,表达式与!=行为相同。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

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;

}

/// <summary>

/// MultiBoolean 对象的等值状态判断,需要指出的是,对于空

/// 值,判断其是否相等没有意义,这里只是判断两个对象是否为同一

/// “状态”,而它们在数学意义上不一定“相等”。

/// 这个方法是重载System.Object.Equals(System.Object obj)

/// 方法的通用接口。

/// </summary>

/// <param name='x'>操作数</param>

/// <returns>返回值</returns>

public override bool Equals(object obj)

{

if(obj.GetType() != this.GetType())

return false;

return this.Equals((MultiBoolean)obj);

}

/// <summary>

/// MultiBoolean 对象的等值状态判断,需要指出的是,对于空

/// 值,判断其是否相等没有意义,这里只是判断两个对象是否为同一

/// “状态”,而它们在数学意义上不一定“相等”。

/// </summary>

/// <param name='x'>操作数</param>

/// <returns>返回值</returns>

public bool Equals(MultiBoolean x)

{

return this.__value == x.__value;

}

/// <summary>

/// MultiBoolean 对象的等值状态判断,需要指出的是,对于空

/// 值,判断其是否相等没有意义,这里只是判断两个对象是否为同一

/// “状态”,而它们在数学意义上不一定“相等”。这个静态方法是

/// 为了用户自定义逻辑体系而预留的,它与==运算符的判等规则不同。

/// </summary>

/// <param name='x'>左值</param>

/// <param name='y'>右值</param>

/// <returns>返回值</returns>

public static bool Equals(MultiBoolean x, MultiBoolean y)

{

return x.__value == y.__value;

}

/// <summary>

/// 获取Hash值,已重载

/// </summary>

/// <returns>对象的Hash值与它的值相对应。</returns>

public override int GetHashCode()

{

return this.__value.GetHashCode ();

}

/// <summary>

/// 将MultiBoolean对象表达为对应的字符串。

/// </summary>

/// <returns>与对象对应的字符串</returns>

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';

}

/// <summary>

/// 将字符串解析为对应的MultiBoolean值。

/// </summary>

/// <param name='input'>待解析的字符串值,可选的范围是'True', 'False', 'Unknown', 'Undefine, 'Nil'。</param>

/// <returns>对应的MultiBoolean值。</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);

}

}

/// <summary>

/// 从数据库字段值中取出逻辑值,并将取转换为MultiBoolean,DBNull对应的值取决于

/// 用户传入的IsNull变量

/// </summary>

/// <param name='DBValue'>数据库接口的GetValue方法返回的通常是一个object,可能的值为True,False,DBNull</param>

/// <param name='IsNull'>DBNull对应的值</param>

/// <returns>返回的MultiBoolean</returns>

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('输入参数不是有效的逻辑值', 'DBValue');

}

/// <summary>

/// 将当前对象封装为T/F/DBNull的

/// 三值对象,用于对数据库访问接口赋

/// 值,这个过程中会损失空值状态,所

/// 以它与ReadDBValue并非互逆操作。

/// </summary>

/// <returns>封装好的对象</returns>

public object ToDBOjbect()

{

switch(Convert.ToInt32(this.__value.real))

{

case 1 :

return (object)true;

case -1 :

return (object)false;

default:

return DBNull.Value;

}

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有