非正式的谬误导致堆栈溢出

Ken*_*Kin 9 c# language-agnostic logic

  • 破碎的代码

    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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

上面的代码希望表达:

结论推断了前提,因为前提暗示了结论.

前提暗示了结论,因为结论推断了前提.

这将是循环推理,肯定会导致堆栈溢出.然后我重新设计如下:

  • 工作代码

    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));
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

但这意味着:

  1. 它失败了正确的逻辑,它不能没有Paradox<T>我最初命名Predicate<T>但与之冲突System.Predicate<T>.

  2. 与代码形成器不同,它T必须实现的缺陷IConvertable.

为了清楚起见,我试图使代码不仅起作用,而且代表逻辑公式,我可以进一步重用它来推理逻辑而不需要T实现约束IConvertable.有没有办法使逻辑正确并摆脱有缺陷的设计?

Tom*_*cek 9

你的问题不是很清楚你想要做什么.您是否尝试在C#中表达一些逻辑谓词?您是否正在尝试编写可以推理逻辑的代码?你想表现出逻辑公式吗?

悖论.在谈论计算中的悖论时,阅读关于lambda演算和Russel悖论的讨论可能会很好(这里有一篇很好的文章).Lambda演算本质上是一种简单的函数式编程语言(想象一下具有lambda函数和应用程序的C#,但没有别的).

它最初是作为数学基础的系统开发的(在计算机被发明之前),但这并没有真正起作用,因为你能够编写没有意义的递归计算(详见文章),但你可以写计算结果如下(以C#表示法):

r(r) = not(r(r)) = not(not(r(r)))
Run Code Online (Sandbox Code Playgroud)

......并且由于没有x = r(r)这样x = not(x)的模型,这个模型作为数学的基础是没有意义的.但它作为编程语言的模型非常有用,您可以在其中编写递归计算 - 尽管它们可能永远不会终止.

代表逻辑.如果要在程序中表示逻辑公式,则可能需要将公式的表示推理分开.这最好用函数式语言(比如F#)完成,但你也可以在C#中完成(只需要输入更多内容).公式的F#表示如下:

type Formula = 
  | Variable of string
  | Negation of Formula 
  | Implies of Formula * Formula
Run Code Online (Sandbox Code Playgroud)

这个想法是公式是一个变量(命名)或另一个公式的否定或一个公式暗示另一个公式的含义.在C#中,您可以表示与类层次结构相同的东西(Formula作为基类和三个派生类.)

然后可以将您的推理实现为操纵公式的方法.在F#中,使用模式匹配可以很容易地完成.在C#中,您可能需要使用类型测试来编写检查参数是否为Variable(然后执行某些操作......)的代码; 如果论证是Negation(然后做某事......)等