When I finished writing this article last week, I suddenly fell short of Internet Explorer, and the writing was completely dispersed. I am also excited. I learned this lesson and did not need to use csdn's online tools. The downside is that when you copy an article to csdn, the format will inevitably go wrong and you have to manually adjust it. When can csdn implement the confluence online backup function? Continue to gossip lambda:
Free vs bounded identifier
Identifiers and variables actually mean one thing. I remember that identifiers are rarely used in Chinese textbooks. However, since the original author used this statement, I followed it. The last time we talked about currying, we solved the problem of processing multiple parameters. Before discussing how to use lambda, we need to solve a subtle but important syntax problem: closure or complete bounding ). There is no essential difference between the bounded logic and the bounded logic in the first-order predicate. The old people familiar with the first-order predicate logic can skip this step with confidence. In fact, bounded definitions are intuitive. Let's look at an example first. Suppose we have a function Lambda x y. (lambda Y. Y + 2) + x +Y+ Z, is Y in Lambda Y. Y + 2 the same as Y in it? Obviously, they are different. To deal with this difference, we introduce bounded. When a Lambda expression is computed, it cannot process unbounded identifiers. When an identifier appears in a Lambda expression parameter and is contained in this Lambda expression, we can say that this identifier is bounded. If an identifier is not included in any expression, we call it a free variable. For example, in the lambda expression above, X appears in Lambda x y. (....) therefore, it is a bounded variable, and its inclusion environment (enclosing context, how to use "context" or "context" to listen awkwardly, it seems that I am the author of "reading. :-D) is the entire Lambda expression. Y in Lambda Y. Y + 2 is also bounded, but its contained environment is lambda Y. Y + 2. The identifier Z does not appear in the list of parameters containing its expressions, so it is a free variable. Here are some examples:
- Lambda X. Plus x y: In this expression, "Y" and "plus" are free variables because they are not any parameters that contain their expressions. X is bounded because it is included in plus x y, and the plus x y parameter has X.
- Lambda x y. Y x: In this expression, X and Y are bounded because they are parameters of this expression.
- Lambda Y. (lambda X. Plus x y): In an embedded expression Lambda X. Plus x y, Y and plus are free variables while X is bounded variables. In the entire Lambda expression, X and Y are bounded: X is in the embedded expression interface, while y is in the entire expression interface. Plus is still free.
We use "free (x)" to represent the set of all free variables in expression X.
A Lambda expression is completely legal only when all its variables are bounded. However, when we examine the subexpressions in a complex expression without considering the context, those subexpressions can have free variables-in fact, it is important to ensure that the free variables in those subexpressions are correctly processed.
Lambda operator calculation rules
In fact, there are two real rules: alpha and beta. Alpha rules are also called conversion rules, while beta rules are also called simplified rules.
Alpha Conversion
The rule that is full of the flavor of Star Trek is actually a RENAME operation. It means that the variable name is not important: given any Lambda expression, we can change the parameter name as long as we change the variable names corresponding to these parameters accordingly.
For example, we have the following expressions:
lambda x . if (= x 0) then 1 else x^2
We use the Alpha rule to change X to Y (write Alpha [x/y] and replace the variable in the logic with one), so we get:
lambda y . if (= y 0) then 1 else y^2
The Alpha operation does not affect the meaning of lambda expressions. However, we will later find that this operation is very important because it enables us to implement such recursive operations.
Beta simplified
Beta simplification is interesting. We only need this rule to allow the lamdba operator to implement what a computer can do.AnyComputing. Through the numerous appearances, we will find that the nature of things is often surprisingly clear and simple. It is just the charm of mathematics to delete the complexity and simplicity.
The Beta rule is nothing more than applying a function (that is, a Lambda expression. It is equivalent to replacing the original function by replacing the bounded variables in the function with the actual values of the corresponding parameters in the application. It sounds a bit confusing (in fact, the original article is more concise), but when you look at an example, you will know that it is actually very simple:
Suppose we want to apply a function :"(lambda x . x + 1) 3". In the beta rule, we can replace the entire expression and replace the X corresponding to the parameter in the function body (that is, "x + 1") with the actual value 3. So the final result is "3 + 1 ".
Here is an example of a slightly complex point:
lambda y . (lambda x . x + y)) q
This expression is interesting, because after applying this expression, we can get another expression. That is to say, it is an expression used to generate expressions. (Speaking Of This, developers playing dynamic languages can laugh and those playing C/C ++/Java can drool ). When beta is simplified for this expression, we replace all the variables corresponding to the parameter Y with the actual value Q. The result is "Lambda X, X + q ".
Another example:
"(lambda x y. x y) (lambda z . z * z) 3". This function with two parameters applies the first parameter to the second parameter. When we calculate its value, we replace the variable X in the first Lambda expression with Lambda Z. z * z, replace y with 3, and get (lambda Z. z * z) 3. To simplify the application of beta for this result, we get 3*3.
Strict definitions of Beta are as follows:
lambda x . B e = B[x := e] if free(e) /subset free(B[x := e]
The condition at the end of this definition, "If free (e)/subset free (B [X: = E])" shows the reason for Alpha conversion: we can implement beta simplification only when Beta simplification does not cause conflicts between bounded and free variables. If a variable "Z" is a free variable in "E", we must ensure that beta simplification does not make "Z" A Bounded variable. If the bounded variable in B is the same as the free variable in "E", we must first use Alpha conversion. The formal definition is not intuitive enough, and the intuitive description is not concise enough. For example, gargle:
Given an expression, Lambda Z. Lambda x. x + Z. Suppose we want to apply this expression:
(lambda z . (lambda x . x + z)) (x + 2)
In the actual parameter "(x + 2)", X is a free variable. X is not a free variable of the expression Lambda x. x + Z. That is to say, free (e)/subset free (B [X: = E]) is not true. If we break the beta simplification rules and start beta simplification, we will get:lambda x . x + x + 2
The free variable in "x + 2", X, is now bounded. If we apply the result to 3: (lambda x. x + 2 + 2) 3, we get 3 + 3 + 2.
What if we follow normal procedures?
Application Alpha [x/y]:lambda z . (lambda y . y+z)) (x + 2)
Application BETA:lambda y . y + x + 2) 3
Apply beta again:3 + x + 2.
"3 + X + 2" and "3 + 3 + 2" are very different!
That's all about the rules. We can also selectively Add a so-called ETA-simplification, but it is not necessary. Skip this step. The system we have discussed is a complete Turing computing system. So what is the use of this system? How can we make this system truly useful? Well, to illustrate these problems, we must first define some basic functions so that we can perform arithmetic, conditional testing, recursion, and so on. These will be discussed in future posts.
We have not talked about models suitable for Lambda operators (the author of good math bad math discusses models here ). Models are also important. Logic developed a complete model after years of studying Lambda operators. In addition, although the lambda operator seems correct earlier, it failed to create a model for it. This was very interesting at the time. You know, after all, there is no practical significance for a system without an effective model.