Prolog is said to be very bad for numerics.
Can we prove the contrary and like plot the following function?
We need to plot the formula where y in a range [k,k+17) for a very large k,
so bignums
could be helpful. But unfortunately the formula looks like a float formula.
Related
Context
I started teaching myself lambda calculus last night and I am trying to determine if what I understand so far is correct.
Understanding
SKK is equivalent to the Identity combinator, I.
Where L stands for lambda:
S = LxLyLz((xz)(yz))
K = LxLy(x)
K essentially takes the next 2 (lambda) terms and gives back the first of those. S seems a little more complicated in the untyped lambda calculus.
My Interpretation
SK(any-lambda-term) is also equivalent to I.
I.e. the application of the application of S to K to Any-lambda-term is equivalent to the Identity combinator:
((S K)(Any)) = I = S K K = ((S K)(K))
I am using the convention of “left-association” in my above notation, if that helps (And I tried to make that clear in the 4th term above with parentheses. Everything I have read so far seems to use this convention).
Reasoning
S K = LyLz((K z)(y z))
The next lambda term will be substituted for y, let the term be Y.
S K Y = Lz((K z)(Y z))
(Y z) is the application of Y to z, also a lambda term.
(K z)returns the constant function that returns z, given another term input: (Y z).
Is my interpretation true? If not, can you provide an explanation? I would greatly appreciate it. Particularly if a sort of order of operations can be explained—I regularly find myself confused when considering when to evaluate. Perhaps that will be refined with practice.
Your intuition is correct, but an intuition proves nothing (alas...)
So, how can we prove your statement? Simply by showing that SKK and SKS have the same behaviour. "Behaviour" is an informal notion, which is formally capture by "semantics": if SKK and SKS are equals, then they should always reduce to the same term, according to the SKI-calculus semantics.
Now, there is a deep question, which is: what are the SKI-calculus? Actually, there is not a single way to answer that. What you implicitly do in your question is that you express SKI in terms of λ terms and you rely on the semantics of the λ calculus. This is absolutly correct. An other way to do it could have been to define directly SKI semantics. For instance, if you look at the wikipedia page, you can see that the semantics are not defined with lambda terms (and the fact that it correspond to lambda term is a (nice and expected) side effect). In the rest of this answer, I'll take the same approach as you do, and convert SKI terms in λ terms. A good exercise for you is to redo the proof, using the proper SKI semantics.
So, let formalize your question: your question is whether, for any SKI term t, SKKt = SKSt? Well... Let's see.
SKKt is encoded as (λx.λy.λz.(xz)(yz))(λx.λy.x)(λx.λy.x)t in the λ-calculus. We now just have to reduce it to a normal form (I detail every step, each time I reduce the leftmost λ, even tho it is not the fastest strategy):
(λx.λy.λz.(xz)(yz))(λx.λy.x)(λx.λy.x)t
= (λy.λz.((λx.λy.x)z)(yz))(λx.λy.x)t
= (λz.((λx.λy.x)z)((λx.λy.x)z))t
= ((λx.λy.x)t)((λx.λy.x)t)
= (λy.t)((λx.λy.x)t)
= t
So, the encoding of SKKt in the λ calculus reduces to t (as a sidenote, we just proved that SKK is equivalent to I here). To conclude our proof, we have to reduce SKSt and see whether it also reduces to t.
SKSt is encoded as (λx.λy.λz.(xz)(yz))(λx.λy.x)(λx.λy.λz.(xz)(yz))t. Let reduce it. (I don't detail as much this time)
(λx.λy.λz.(xz)(yz))(λx.λy.x)(λx.λy.λz.(xz)(yz))t
= ((λx.λy.x) t)((λx.λy.λz.(xz)(yz)) t))
= (λy.t)((λx.λy.λz.(xz)(yz)) t))
= t
Hurrah! It also reduce to t, so indeed, SKS and SKK are equivalent. It seems that the third combinator is not important: that as soon as you have SK?, it is equivalent to I. As an exercise, you can easily prove it (same strategy, if it is the case, then for any terms t and s, SKts = s). As mentionned above, an other good exercise is to redo the proof without using the λ semantics, but the proper SKI semantics.
Finally, my answer should raise a new question to you: we have two semantics, one that encodes SKI terms into λ terms, and one that does not. The question you may have is: are the two semantics equivalent? What does it mean for two semantics to be equivalent? If you are only starting to teach yourself λ calculus, it may be a bit early to try to answer those questions right now, but you can keep it in a corner of your head for when you'll get more familiar with formal languages.
I already asked a similar question but it was not clear enough, so I decided to rephrase it.
I know that a matrix is an applicative functor but not a monad. I am wondering if there is a simple and practical example of <*> for matrices.
A possible Applicative instance for matrices would be to make it analogous to ZipList. With F a matrix of functions, and X a matrix of values, F <*> X applies each function in F pointwise to each value in X. The result is truncated in each dimension to fit the shortest matrix. pure f gives an infinite matrix with f at each point. As an example example, the pointwise matrix multiplication is then (*) <$> A <*> B.
In stead of truncation and working with infinity, you could fix the shape of the matrix by using a phantom type parameter as used in accelerate. Of course, then you could also declare a Monad instance just like with fixed size ziplists.
From http://www.cse.ohio-state.edu/~gurari/theory-bk/theory-bk-twoli1.html#30007-23021r2.2.4:
Let M = <Q, Σ, Δ, δ, q0, F> be the deterministic finite-state transducer whose transition diagram is given in Figure 2.E.2.
For each of the following relations find a finite-state transducer that computes the relation.
a. { (x, y) | x is in L(M), and y is in Δ* }.
b. { (x, y) | x is in L(M), y is in Δ*, and (x, y) is not in R(M) }.
Yes, this is HW, but I have been struggling with these questions and could at least use pointers. If you want to create your own c. and/or d. examples just to show me HOW to do it rather than lead me to the answers for a. and b. then obviously I'm fine with that.
Thanks in advance!
Since you don't indicate what progress you've made so far, I'm going to assume that you've made no progress at all, and will give overall guidance for how you can approach this sort of problem.
First of all, examine the transition diagram. Do you understand what all the notations mean? Note that the transducer is described as deterministic. Do you understand what that means? Convince yourself that the transducer depicted in the transition diagram is, in fact, deterministic. Trace through it; try to get a sense for what inputs are accepted by the transducer, and what outputs it gives.
Next, figure out what L(M), Δ, and R(M) are for this transducer, since the questions refer to them. Do you know what those notations mean?
Do you know what it means for a transducer to compute a certain relation? Do you understand the { (x, y) | ... } notation for describing the relation?
Can you modify the transition diagram to eliminate the ε/0 transition and merge it into adjacent transitions (which then might output multiple symbols at a single transition)? (This can help, IMHO, with creating other transducers that accept the same input language. More so with part b, in this case, than part a.)
Describe for yourself the transducers you need to create, in a way that's independent of the original transducer. Will these transducers be deterministic?
Create the transition diagrams for these transducers.
I would like to know if there is a straightforward algorithm for rearranging simple symbolic algebraic expressions. Ideally I would like to be able to rewrite any such expression with one variable alone on the left hand side. For example, given the input:
m = (x + y) / 2
... I would like to be able to ask about x in terms of m and y, or y in terms of x and m, and get these:
x = 2*m - y
y = 2*m - x
Of course we've all done this algorithm on paper for years. But I was wondering if there was a name for it. It seems simple enough but if somebody has already cataloged the various "gotchas" it would make life easier.
For my purposes I won't need it to handle quadratics.
(And yes, CAS systems do this, and yes I know I could just use them as a library. I would like to avoid such a dependency in my application. I really would just like to know if there are named algorithms for approaching this problem.)
What you want is equation solving algorithm(s). But i bet that this is huge topic. In general case, there may be:
system of equations
equations may be non-linear, thus additional algorithms such as equation factorization needed.
knowledge how to reverse functions is needed,- for example =>
sin(x) + 10 = z, solving for x we reverse sin(), which is arcsin(). (Not all functions may be reversible !)
finally some equations may be hard-solvable even for CAS, such as
sin(x)+x=y, solve for x.
Hard answer is - your best bet is to take source code of some CAS,- for example you can take a look at MAXIMA CAS source code which is written in LISP. And find code which is responsible for equation solving.
Easy answer - if all that you need is solving equation which is linear and is composed only from basic operators +-*/. Then you know answer already - use old good paper method
- think of what rules we used on paper, and just re-write these rules as symbolic algorithm which manipulates equation string.
good luck !
It seems like what you're interested in doing is maintaining a system of linear equations and then, at any time, being able to solve for one variable in terms of all the others. If you encode the relationships as a matrix, it seems like you could then reduce the matrix to some nice form (for example, reduced row echelon form) to get the "simplest" dependencies amongst the variables (for some nice definition of "simplest.") Once you have the data like this, you should be able to read off all the dependencies by just looking at some row that has a nonzero entry for the variable in question, then normalizing it so that the variable has coefficient one.
A note - in general, you won't always get a unique solution for each variable. For example, given the trivial equations
x = y
x = z
Then solving for z could yield either "z = x" or "z = y," depending on how much simplification you want. Or alternatively, in a setup like
x = 2y + 3w
x = 9z
Returning a value for x could hand back either expression, or their sum over two, or a whole bunch of other things that are all technically true but not necessarily useful. I'm not sure how you'd handle this, but depending on the form of your equations you can probably find a way to handle it.
Convert your expression into a data structure (tree) in reverse Polish notation. Your tree is made up of nodes, each node has an operation, a left and a right. Each of the left and right can be a symbol (eg: "x") or another node. For example:
(x + (a + b))
Would become:
(+ x (+ a b))
Or in JSON:
["+", "x", ["+", "a", "b"]]
Your original expression m = (x + y) / 2 would look like this:
m = ["/", ["+", "x", "y"], "2"]
One of your desired expressions (solving for x) looks like this:
x = ["-", ["*", "m", "2"], "y"]
Can you see that the tree of expressions has been turned inside out and each operator has been reversed? The "-" is the reverse of the "+" and now wraps the "*" which is a reverse of the "/". The:
["+", "x", "y"]
Becomes:
["-", (something), "y"]
Where (something) is a reversal of the outer expression recursively. To try to explain the process: a) recursively descend the expression tree until you find the node containing the symbol you want to solve for, b) make a new node containing a reverse of this nodes operation, c) replace the symbol you want to solve for with the reversed outer expression, recursively doing this as you progress back outwards.
There are various simple ways in which the initial equation can be modified, performing the correct modifications in the correct order will lead to the correct solution. So how about seeing this as a search or even a pathfinding problem?
Given a set of constraints, I would like to efficiently generate the set of values.
Suppose I have a few constraints on my Thungus[1]:
goodThungus(X) :-
X > 100,
X < 1000.
sin(X) = 0.
Now, I can check a Thungus by asking:
goodThungus(500).
I would like to generate all good Thungi. I'm not sure how to do that; I'm really not sure about how to do it efficiently.
Note: this of course has to be a computable generation.
[1] Arbitrary object selected for this example.
What you are asking for can't be done in the full general case: imagine doing f(X) = 0 where f is a function for which the roots cannot be analytically determined, for example. Or suppose f(X) is the function "does the program X halt?". No computer is going to solve that for you.
Your options are basically to either:
Limit the set of constraints to things that you can reason about. e.g. inequalities are good because you can identify ranges, then do intersections and unions on ranges efficiently etc.
Limit the set of values to a small enough number that you can test them individually against each of the constraints
UPDATE: For the kind of constraints stated in the question (ranges of real values and real-valued functions that can be analytically solved and have a finite number of solutions within any range) I would suggest the following approach:
Write a generating function that can iteratively return solutions for you function within a given range... this will need to be done analytically e.g. exploiting the fact that sin(X)=0 implies X=n*pi where n is any integer.
Do interval arithmetic and bounding on your range constraints to work out the range(s) that need to be scanned (in the example you would want the range 100 < X < 1000)
Apply your generating function to each of the target ranges in order to create all of the possible solutions.
I'll preface my suggestion by stating that I'm no expert in using numerical constraint logic programming systems, but here goes...
On the surface, I'd think that solving this kind of problem in PROLOG would be best suited to a numerical constraint logic programming system, perhaps such as CLP(R) (for reals) in SWI-PROLOG; unfortunately, the specific problem you've asked for is seeking to solve for a set of constraints including a non-linear constraint, which seems to be not well or widely supported amongst PROLOG implementations; instead, they seem to deal mainly with linear constraints and often have limited support for non-linear constraints such as X = sin(Y), for example.
Take SWI-PROLOG's CLP(R) library, and the following example program:
:- use_module(library(clpr)).
report_xsq_zeros :-
findall(X, {0 = (X * X) - 10}, Results),
write_ln(Results).
report_sin_zeros :-
findall(X, {0 = sin(X)}, Results),
write_ln(Results).
Now, executing report_xsq_zeros gives us:
?- report_xsq_zeros.
[3.16228, -3.16228]
true.
Here, the system correctly computed the zeros of the quadratic x^2 - 10, which are indeed approximately 3.16228 and -3.16228, where the range of X was unbounded. However, when we execute report_sin_zeros, we get:
?- report_sin_zeros.
[0.0]
true.
We see that the system only computed a single zero of the function sin(X), even though the range of X was indeed also unbounded. Perhaps this is because it is recognized that there are an infinite number of solutions here (though I'm only guessing...). If we were to program what you've asked for:
report_sin_zeros :-
findall(X, {X > 100, X < 1000, 0 = sin(X)}, Results),
write_ln(Results).
We get no results, as the underlying system only computed a single zero for sin(X) as shown earlier (i.e., binding X to 0.0 which lies outside the stated range):
?- report_sin_zeros.
[]
true.
I conclude that I've either not demonstrated proper usage of SWI-PL CLP(R) (I suggest you look into it yourself), or it won't solve your specific (non-linear) problem. Other CLP(R) implementations may behave differently to SWI-PROLOG CLP(R), but I don't have them installed so I can't check, but you could try SICSTUS CLP(R) or others; the syntax looks similar.
He is searching any X in [100..1000] for that sin(x) = 0. But this is a pure mathematical problem, and not meant for relational logical deduction / backtracking. simple Prolog is not suited for this?