How get Y combinator through S combinator or others? - lambda-calculus

I have the equation Y = FY (fixed point equation). How to get of it the equation for F through other combinator (in particular S- combinator with first fixed parameter)?

There's no way to do this -- consider the functions g and g ∘ g. Then Y(g) and Y(g ∘ g) are both g(g(g(g(g(...))))), so there's no way to go from Y(F) to F in general.

Related

Asymptotic analysis of agda functions inside agda

Is it possible to asymptotically analyze agda functions' runtime or memory inside agda itself? I'm trying to come up with something like this. Suppose I have this agda function:
data L : Nat → Set where
[] : L zero
list : ∀ {n} → Nat → L n → L (suc n)
f : ∀ {n} → L n → Nat
f [] = 0
f (list x xs) = f xs
I want to prove a theorem in agda that'd ultimately mean something like f ∈ O[n]. However, this is rather hard since I now need to prove something about the implementation of f rather than its type. I tried using some reflection and metaprogramming, but without much success. I guess the algorithm I have in my mind is something like getting all terms of f one by one like lisp.
The biggest trouble is, obviously, O[n] is not well defined, I need to be able to construct this class from n of L n. Then, I need f as f : L n -> Nat so that thm : ∀ {n} -> (f : L n -> Nat) -> f ∈ (O n). But then f is now not bound to the f we're interest in. Instead, it's any function f from a list to a natural. Therefore, this is clearly false, so it cannot be proven.
Is there a way to prove something like this?

How would you write ∀ y ∈ R+, ∃ z ∈ R, e^z = y in pseudocode?

I’m reading about proofs, currently reading Mathematics for Computer Science by Eric Lehman and Tom Leighton, they illustrate in a sample proposition that "as z ranges over the real numbers, e^z takes on every positive, real value at least once". I'm having trouble fully grasping this proposition.
I am trying to approach this is as a programmer and think of what it would look like in pseudocode if I were to see if it was true.
pr = [ all real positive numbers ]
r = [ all real numbers ]
for y in pr:
for z in r:
e = pow(y, z)
if e != y:
goto outer
print "this is true";
outer
Is this what they are proposing?
∀ y ∈ R+, ∃ z ∈ R, e^z = y
Is saying that for all y in the set of positive real numbers, there exists a z in the set of real numbers, such that exp(z) = y.
You can't really create a program to verify that this is true. Most basically because you will encounter one of the following problems
Floating point math imprecision (essential read Is floating point math broken?)
The reals are infinite
You could check this over every floating point number (which would take a very long time but is still theoretically able to be computed), but you would
Likely come up with a situation where there is no z such that exp(z) = y because such a z does not exist exactly enough in the set of floating point numbers to give you exp(z) = y
Even if there was a z for every y in the set of floating point numbers, this would not prove exp(z) = y for all y in R+ and z in R.
So on the whole, yes you're pseudocode somewhat represents the idea, but it's not viable or logical to check this on a computer or really as much think about this as a computing problem.
Edit:
The best way to think about this programmatically would be like this
R = [SET OF ALL REALS]
R+ = FILTER (> 0) R
(MAP (exp) R) == R+
N.B. exp means e^n where e^x = SUM [ (x^k)/(k!) | k <- [SET OF ALL NATURALS]] which is approximately 2.718^x.
If you imagine that it were possible to enumerate all the positive real numbers, and moreover to do so in finite time, then pseudocode for your thought experiment might look more like this:
pr = [ all real positive numbers ]
r = [ all real numbers ]
for y in pr:
for z in r:
e = exp(z)
if e == y:
goto outer
print "false"
stop
outer:
print "true"
The key differences from your pseudocode are:
(technical) changing pow(y, z) to exp(z). This is the exponential function on z, or equivalently, the number e raised to the zth power
The proposition is found to be true (and the algorithm prints that result) only if the outer loop runs to completion
If on any iteration of the outer loop, the inner one does run to completion (indicating that y for that iteration is not the exponential of any real number) then the proposition is proved false. In that case the algorithm prints that result and stops. Only one such real number y is needed for the whole proposition to fail.
Of course, an entirely different, mathematical way to describe the proposition is that it says the natural logarithm is defined and evaluates to a real number for all positive real arguments. That follows because the natural logarithm is the inverse of the exponential, so if you take the logarithm of both sides of e^z = y, you get z = log(y).
The proposition is proven by a program that will find z ∈ R given any y ∈ R+, so:
z = log(y);

Benchmark for fast algorithms whose task is function minimization

Is there a set of test functions to measure the performance (in terms of speed, maybe trading off with accuracy) of a given algorithm whose task is to find a/the global minimum of a real-valued function over a given interval? Eventually: is this problem an open problem or does there exist a theoretical best algorithm for such a task?
EDIT: there are no restrictions on the function, other that it should be bounded.
With no restrictions on the function except boundedness, it does not seem possible to always find its global minimum, let alone in reasonable time.
Consider the family of real-valued functions defined on [0..1]:
f (x0) = y0
f (x) = 0 for all other x in [0..1]
For any fixed x0 in [0..1] and y0 < 0, the minimum is at x0.
Still, any algorithm with no prior knowledge of x0 will have a hard time finding it.
Take a function that is 0 in every point where you evaluate f (x), and c for an unknown c > 0 for every point where you don't evaluate f (x). If you want it continuous, then if x is between a and b, where a and b are the neighbouring points where you evaluated f (a) and f (b), then f goes linear from f (a) = 0 to f ((a + b)/2) = c and back linear to f (b) = 0.
Clearly every time you evaluate f (x), you get a zero. Since you never evaluate anything else, your algorithm cannot conclude that the global maximum is anything but zero - which is wrong.

Dijkstra Algorithm on a graph modeling a network

We have a directed graph G = (V, E) for a comm. network with each edge having a probability of not failing r(u, v) (defined as edge weight) which lies in interval [0, 1]. The probabilities are independent, so that from one vertex to another, if we multiply all probabilities, we get the the probability of the entire path not failing.
I need an efficient algorithm to find a most reliable path from one given vertex to another given vertex (i.e., a path from the first vertex to the second that is least likely to fail). I am given that log(r · s) = log r + log s will be helpful.
This is what I have so far -:
DIJKSTRA-VARIANT (G, s, t)
for v in V:
val[v] ← ∞
A ← ∅
Q ← V to initialize Q with vertices in V.
val[s] ← 0
while Q is not ∅ and t is not in A
do x ← EXTRACT-MIN (Q)
A ← A ∪ {x}
for each vertex y ∈ Adj[x]
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
s is the source vertex and t is the destination vertex. Of course, I have not exploited the log property as I am not able to understand how to use it. The relaxation portion of the algorithm at the bottom needs to be modified, and the val array will capture the results. Without log, it would probably be storing the next highest probability. How should I modify the algorithm to use log?
Right now, your code has
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
Since the edge weights in this case represent probabilities, you need to multiply them together (rather than adding):
do if val[x] * p(x, y) > val[y]:
val[y] = val[x] * p(x, y)
I've changed the sign to >, since you want the probability to be as large as possible.
Logs are helpful because (1) log(xy) = log(x) + log(y) (as you said) and sums are easier to compute than products, and (2) log(x) is a monotonic function of x, so log(x) and x have their maximum in the same place. Therefore, you can deal with the logarithm of the probability, instead of the probability itself:
do if log_val[x] + log(p(x, y)) > log_val[y]:
log_val[y] = log_val[x] + log(p(x, y))
Edited to add (since I don't have enough rep to leave a comment): you'll want to initialize your val array to 0, rather than Infinity, because you're calculating a maximum instead of a minimum. (Since you want the largest probability of not failing.) So, after log transforming, the initial log_val array values should be -Infinity.
In order to calculate probabilities you should multiply (instead of add) in the relaxation phase, which means changing:
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
to:
do if val[x] * p(x, y) < val[y]:
val[y] = val[x] * p(x, y)
Using the Log is possible if the range is (0,1] since log(0) = -infinity and log(1) = 0, it means that for every x,y in (0,1]: probability x < probability y than: log(x) < log(y). Since we are maintaining the same relation (between probabilities) this modification will provide the correct answer.
I think you'll be able to take it from here.
I think I may have solved the question partially.
Here is my attempt. Edits and pointers are welcome -:
DIJKSTRA-VARIANT (G, s, t)
for v in V:
val[v] ← 0
A ← ∅
Q ← V to initialize Q with vertices in V.
val[s] ← 1
while Q is not ∅ and t is not in A
do x ← EXTRACT-MAX (Q)
A ← A ∪ {x}
for each vertex y ∈ Adj[x]
do if log(val[x]) + log(p(x, y)) > log(val[y]):
log(val[y]) = log(val[x]) + log(p(x, y))
Since I am to find the highest possible probability values, I believe I should be using >. The following questions remain -:
What should the initial values in the val array be?
Is there anything else I need to add?
EDIT: I have changed the initial val values to 0. However, log is undefined at 0. I am open to a better alternative. Also, I changed the priority queue's method to EXTRACT-MAX since it is the larger probabilities that need to be extracted. This would ideally be implemented on a binary max-heap.
FURTHER EDIT: I have marked tinybike's answer as accepted, since they have posted most of the necessary details that I require. The algorithm should be as I have posted here.

Is union is regular expression different from union in set?

In mathematical set we have
A={1,2,3}
B={4,5,6}
A U B = B U A = {1,2,3,4,5,6} ={6,5,2,3,4,1} //order does not matter
But in theory of computation we get
a u b is either a or b but not both
also in a* u b* we get aaa or bbb but not aaabbb or bbbaaa as order does not matter in union.
why is that?
Thanks
Rahman
why?
No. In formal language theory, there is a correspondence between regular expressions and regular sets over an alphabet Σ. The function L maps a regular expression u to the corresponding regular set L(u); conversely, every every regular set A corresponds to a regular expression in L-1(A):
L(∅) = ∅
L(λ) = {λ}
L(a) = {a} (for all a ∈ Σ)
L(uv) = L(u)L(v) = {xy ∈ Σ* : x ∈ L(u) ∧ x ∈ L(v)}
L(u|v) = L(u) ∪ L(v) = {x ∈ Σ* : x ∈ L(u) ∨ x ∈ L(v)}
L(u*) = ∪[i ∈ ℕ] L(u)i = ∪[i ∈ ℕ] {xi ∈ Σ* : x ∈ L(u)}
The union of regular expressions corresponds to the union of regular sets, which is the familiar union operation from set theory. A regular expression u matches a string x iff x is a member of the corresponding set L(u). Therefore, u|v matches x iff x is a member of L(u) ∪ L(v).
This probably still belongs on math overflow, and you haven't really supplied enough context for a definitive answer so I'm going to make some assumptions.
Union Types in most languages might give you an expression like:
type C = B union A
So type C is the type/set of all values that might exist in the types B or C. So a value x of type B is also a value of type C.
And this is indeed the case for many languages. However stack overflow is targeting the more concrete world of programming. Math overflow is will have more theorists that will be better able to answer your question.

Resources