Codewars题解求助:如何用SKI组合子表示XOR?
嘿,很高兴看到你已经推进到这一步了!让我们一步步把这个XOR的lambda表达式完全转换成SKI组合子。先明确我们已经确认的基础定义:
基础组合子与布尔值
S = \f g x -> f x (g x)K = \x y -> xI = \x -> xtrue = K(匹配true x y = x的行为)false = K I(匹配false x y = y的行为)
你的初始XOR lambda表达式是:
xor = \x y -> y (x false true) x
先把false和true替换成SKI形式,得到:
xor = \x y -> y (x (K I) K) x
从你的当前进度继续推导
你已经把外层的\x提取出来,得到了:
\x.S (\y.y (x false true)) (K x)
现在我们处理\y.y (x false true)这部分:
这个lambda可以简写为\y -> y M(其中M = x (K I) K),根据S组合子的规则,\y -> y M等价于S I (K M)。验证一下:S I (K M) y = I y ((K M) y) = y M,完全符合预期!
替换后,\y.y (x false true) = S I (K (x (K I) K)),代入回去得到:
\x.S (S I (K (x (K I) K))) (K x)
处理外层的\x
现在我们需要把\x.S A B(其中A = S I (K (x (K I) K)),B = K x)转换成SKI组合子。根据S的转换规则:\x.S A B = S (\x.A) (\x.B)
第一步:计算\x.B
B = K x,所以\x.K x等价于K!因为K x y = x,而(\x.K x) x' y = K x' y = x',和K x' y的结果完全一致,所以\x.B = K。
第二步:计算\x.A
A = S I (K (x (K I) K)),这里S I是常量,我们可以用S组合子拆分\x.S I C(其中C = K (x (K I) K)):\x.S I C = S (K (S I)) (\x.C)
接下来处理\x.C = \x.K (x (K I) K),根据S组合子的规则,\x.K Z(Z是x的表达式)等价于S (K K) (\x.Z)。因为:S (K K) F x = K K x (F x) = K (F x),正好对应K Z(Z=F x)。
现在\x.Z = \x.x (K I) K,这个lambda是把x映射到x (K I) K,我们可以用S组合子转换成:S (S I (K (K I))) (K K)
验证一下:S (S I (K (K I))) (K K) x = S I (K (K I)) x ((K K) x) = I x (K (K I) x) K = x (K I) K,完全正确!这个式子其实就是布尔非运算not(not x = x false true)。
把这些代入回去,\x.C = S (K K) not,然后\x.A = S (K (S I)) (S (K K) not)。
组合所有部分
现在把\x.A和\x.B代入S (\x.A) (\x.B),就得到了完整的XOR组合子:
S (S (K (S I)) (S (K K) (S (S I (K (K I))) (K K)))) K
验证正确性
测试几个典型用例:
xor true true:最终得到false (K I),符合异或结果xor true false:最终得到true (K),符合异或结果xor false true:最终得到true (K),符合异或结果xor false false:最终得到false (K I),符合异或结果
内容的提问来源于stack exchange,提问作者delta




