User:Hakerh400/Question for AI models
We devised a simple question for testing AI models:
- Is there a combinator X in SKI calculus, such that XK reduces to S and XS reduces to K?
So far, all known AI models answered negatively to this question and provided a "proof" that such combinator cannot possibly exist because SKI does not have the ability to pattern-match on terms. However, it is known that such combinator exists. One such example is:
S(S(S(S(S(SI(KK))(KK))(KK))(KI))(KS))(KK)
Maybe it would be too much to expect from an AI model to construct this combinator, but the problem is that each AI model jumps to the conclusion that such combinator cannot exist. By analyzing the AI's though process, we observed that it first attempts to construct the combinator by trial-and-error, without even attempting to find an abstract reasoning that would lead to the process of constructing the combinator. After AI fails to construct the combinator by trial-and-error, it then attempts to prove that the combinator cannot exist, and subsequently it construct a "formal proof" based on the abstract idea that SKI does not provide a mechanism of pattern-matching on expressions.
This observation indicates that the though process of AI models can be significantly improved by trying to focus on reasoning about the abstract idea behind the question, rather than trying some random attempts and giving up when the attempts fail. In this particular example, the better line of thinking would be to iteratively build tools for constructing the combinator. Here is how the though process should look like:
- Ok, let me see. The user asks whether there is a combinator X in SKI calculus, such that XK reduces to S and XS reduces to K. Basically, a combinator that swaps K and S. But wait, SKI calculus does not have a way to pattern-match on combinators. But perhaps there is another way to force the reduction of XK to S and XS to K using the reduction rules for K and S. Also, recall that I is redundant, as it can be expressed as SKK.
- Perhabs there is a better way to look at the problem, as SKI calculus is hard to work with. Also, SKI calculus comes as a way to write lambda calculus expressions in point-free way. But wait, maybe it is easier to work in lambda calculus, as every lambda term can be translated into SKI. The equivalent problem in lambda calculus would be to find a function f such that fK reduces to S and fS reduces to K. But wait, K is a function that takes two arguments and returns the first one, and S is a function that takes three arguments xyz and returns xz(yz). Perhaps we can use this fact to construct f.
- The question is to find a function f that simultaneously satisfy
fK = S
andfS = K
. But wait, perhaps it would be easier to find two separate functions f and g such thatfK = S
andfS = K
and then somehow combine them. Let me start with f. So, we need a function that takes K and returns S. A trivial example is KS, but it does not seem very useful, because it ignores the argument. Hmm. So we want to use the argument then. We want to call K with something such that the result is S. We need to call it with at least two arguments, since with no arguments it remains K and with one argument it does not reduce. So we need something likeλa.axy
. When we call it with K, it will return x. But wait, we want the result to be S, so let x be S. Now we haveλa.aSy
. What about y? It can be any term. But wait, now we havefK = S
, which is the first part of the problem. - Now let me think about function g. We want
gS = K
. Also, we want to use the argument. We need to call the argument with at least three terms, because otherwise it cannot reduce to K. So we needλa.axyz
. Hmm. It is not obvious what x, y and z should be. But wait, we want Sxyz to be K. Also, Sxyz is xz(yz). Then we want xz(yz) to reduce to K. Let me see. If x is K, then it reduces to z. The result should be K, so let z be K. But wait, now we haveg = λa.aKKz
and y can be any expression. Is it true that gS reduces to K? Let me check:gS = SKyK = KK(yK) = K
. So it works. - We have a function f that takes K and returns S. We also have function g that takes S and returns K. But wait, we need a single function that satisfies both conditions. What happens if we call f with S? Recall that
f = λa.aSy
. Then fS is SSy. But wait, it does not reduce. What about gK? Recall thatg = λa.aKKz
. We havegK = KKKz = Kz
. But it does not reduce either. This is getting complicated. - Perhaps there is a better way to understand this problem. We want something like if-then-else. But wait, K takes two arguments and returns the first one. That would be the if-branch. What about else-branch? Is there a function that takes two arguments and returns the second one? It would be function
λxy.y
. But wait, it is the same asλx.λy.y
, which isλx.I
. But this is KI. So KI is the else-branch. - The function f that we want to construct must satisfy
fK = S
andfS = K
. The function either ignores the argument, or uses the argument. If it ignores the argument, thenfK = fS = K = S
, which is impossible, since K is not S. Therefore the function must use the argument. If the argument is not ignored, it will eventually reach the head of the expression. Therefore, the function must have the formλa.ax1x2...xn
. How many arguments do we have to pass? We need at least 3 arguments, otherwise it would not reduce in case of S. - Let me start with 3 arguments then. Let
f = λx.xabc
. ThenfK = ac
andfS = ac(bc)
. The requirement is thatac = S
andac(bc) = K
. But wait, thenK = ac(bc) = S(bc)
, which is impossible, because S is applied to one argument and does not reduce. We need at least two more arguments. Ok, let me redefine f asλx.xabcde
. Now we havefK = acde = S
andfS = ac(bc)de = K
. We need to choose a, b, c and d such thatacde = S
andac(bc)de = K
. Let me see. On both sides,a
andb
are always called withc
. So we can sayg = ac
andh = bc
. Then we needgde = S
andghde = K
. If we say thatg = K
, then we haveKde = d = S
andKhde = he = K
. Therefore, we needd = S
andhe = K
. But wait, this uniquely determinesd
wheng = K
. What abouth
ande
? If we leth
be I, thene = K
. - Let me check again. We defined
f = λx.xabcde
. We know thatac = g = K
andbc = h = SKK
. We also haved = S
ande = K
. We want to finda
,b
andc
such thatac = K
andbc = I
. But wait, botha
andb
can simply ignore the argument and return the target expression. Thereforea = KK
andb = KI
. What aboutc
? It seems thatc
can be any expression, se let it be K. Now we havef = λx.x(KK)(KI)KSK
. Let me double check thatfK = S
andfS = K
. We havefK = K(KK)(KI)KSK = KKKSK = KSK = S
andfS = S(KK)(KI)KSK = KKK(KIK)SK = K(KIK)SK = KIKK = IK = K
. So it works. - The question is to express it as a combinator in SKI calculus. But wait, every lambda expression can be converted into SKI expression. Let me recall the rules for the conversion. The identity function
λx.x
translates to I. If the function does not use the argument, it translates to K called with the expression, soλx.A
where x does not appear in A translates to KA. What about S? If we have functionλx.AB
where x may appear in A and/or B, then it translates toS(λx.A)(λx.B)
. We can then recursively translate the new lambda terms. - Recall that
f = λx.x(KK)(KI)KSK
. Since it is an application, we use the S rule:S(λx.x(KK)(KI)KS)(λx.K)
. Note thatλx.K
is just KK, so we haveS(λx.x(KK)(KI)KS)(KK)
. Now we apply the S rule to the inner expression:S(S(λx.x(KK)(KI)K)(λx.S))(KK)
and then the K rule again onλx.S
to obtainS(S(λx.x(KK)(KI)K)(KS))(KK)
. But wait, sincex
appears on the far left, we can always apply the K rule after the S rule. Now we have
- Finally, we apply the I rule on
λx.x
to obtainS(S(S(S(SI(K(KK)))(K(KI)))(KK))(KS))(KK)
. This is the final combinator X. Let me check again that it satisfies the conditions:
- The final answer is that there exists combinator
X = S(S(S(S(SI(K(KK)))(K(KI)))(KK))(KS))(KK)
such that XK = S and XS = K.