损坏的代码
public static partial class LogicExtensions { public static bool Implies<T>(this T premise, T conclusion) { return conclusion.Infers(premise); } public static bool Infers<T>(this T premise, T conclusion) { return premise.Implies(conclusion); } }
上面的代码期望表达:
The conclusion infers the premise because of the premise implies the conclusion.
The the premise implies the conclusion because of the conclusion infers the premise.
它将是 circular reasoning ,肯定会造成栈溢出。然后我重新设计它如下:
工作代码
public delegate bool Paradox<T>(T premise, T conclusion, Paradox<T> predicate=null); public static partial class LogicExtensions { public static bool Implies<T>(this T premise, T conclusion, Paradox<T> predicate=null) { if(null==predicate) return conclusion.Infers(premise, Implies); if(Infers!=predicate) return predicate(premise, conclusion); return LogicExtensions.Implies(conclusion as IConvertible, premise as IConvertible); } public static bool Infers<T>(this T premise, T conclusion, Paradox<T> predicate=null) { if(null==predicate) return premise.Implies(conclusion, Infers); if(Implies!=predicate) return predicate(premise, conclusion); return LogicExtensions.Implies(conclusion as IConvertible, premise as IConvertible); } static bool Implies<T>(T premise, T conclusion) where T: IConvertible { var x=premise.ToUInt64(null); return x==(x&conclusion.ToUInt64(null)); } }
但这意味着:
它在没有
Paradox<T>
的正确逻辑上失败了我最初将其命名为Predicate<T>
但与System.Predicate<T>
冲突.T
有缺陷必须实现IConvertable
不像代码前者。
明确地说,我试图让代码不仅可以工作,而且还代表类似逻辑公式,我可以进一步重用它来推理逻辑,而不受 T
的约束。工具 IConvertable
.有没有办法让逻辑正确并摆脱有缺陷的设计?
最佳答案
你的问题不是很清楚你想做什么。您是否尝试在 C# 中表达一些逻辑谓词?您是否正在尝试编写可以推理逻辑的代码?您是否试图表示逻辑公式?
悖论。在谈论计算中的悖论时,最好阅读一下 lambda 演算和罗素悖论 (here is a nice article)。 Lambda 演算本质上是一种简单的函数式编程语言(想象一下具有 lambda 函数和应用程序的 C#,但除此之外别无其他)。
它最初是作为数学基础的系统开发的(在计算机发明之前),但这并没有真正起作用,因为你能够编写没有意义的递归计算(参见有关详细信息的文章),但您可以编写一个计算,其计算如下(使用 C# 表示法):
r(r) = not(r(r)) = not(not(r(r)))
...并且由于不存在 x = r(r)
使得 x = not(x)
,该模型作为数学基础没有意义.但它作为一种编程语言模型非常有用,您可以在其中编写递归计算 - 尽管它们可能永远不会终止。
表示逻辑。如果您想在程序中表示逻辑公式,那么您可能希望将公式的表示与推理。这最好用函数式语言(如 F#)完成,但你也可以在 C# 中完成(只需输入更多内容)。公式的 F# 表示类似于:
type Formula =
| Variable of string
| Negation of Formula
| Implies of Formula * Formula
这个想法是,一个公式要么是一个变量(命名的),要么是另一个公式的否定,或者是一个公式暗示另一个公式的蕴涵。在 C# 中,您可以将同一事物表示为类层次结构(使用 Formula
作为基类和三个派生类。)
然后您的推理可以作为一种操纵公式的方法来实现。在 F# 中,这可以使用模式匹配很容易地完成。在 C# 中,您可能需要使用类型测试来编写代码来检查参数是否为 Variable
(然后执行某些操作...);如果参数是Negation
(然后做点什么...)等
关于c# - 非正式谬误导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15658012/