Fixed point of K combinator - lambda-calculus

The K combinator is K := (λxy.x) and the fixed point combinator is Y := λf.(λx.f x x) (λx.f x x). I tried to calculate YK:
YK = (λx.Kxx)(λx.Kxx) = (λx.x)(λx.x) = (λx.x) = I
So because YK is the fixed point of K:
K(YK) = YK
KI = I
KIe = Ie = e
for any e. But KIe should be equal to I!

You're not starting with the correct definition of the Y-combinator. It should be Y := λf.(λx.f (x x)) (λx.f (x x)) (note the parentheses around x x).
Since lambda-calculus is left-associative, f x x is equal to (f x) x, which obviously doesn't work.
Using the correct definition, we get
Y K := (λf.(λx.f (x x)) (λx.f (x x))) K
(λx.K (x x)) (λx.K (x x))
K ((λx.K (x x)) (λx.K (x x)))
K (Y K)
Since Y K doesn't reduce to I, the following substitution is not allowed.
K (Y K) = Y K
K I = I
So, K I e is simply
K I e := (K I) e
((λx.λy.x) I) e
(λy.I) e
I

Related

How to find the number of solutions of modular equation?

Find the number of solutions of 𝑥 = x (mod m)
Let p and q be the primes.
You can break a modular equation into separate equations if the factors are coprime.
This means that 𝑥**2 = x (mod m) is equivalent to 𝑥**2 = x (mod p) and 𝑥**2 = x (mod q).
Each of these can be factorized as x(x-1)=0 => x=0 or x=1.
So you know that x is 0 or 1 modulo p, and x is 0 or 1 modulo q. Each choice has 1 solution modulo m by the chinese remainder theorem so there will be 4 solutions.
2 are easy (x=0 and x=1). The other two can be found with the extended Euclidean algorithm as follows:
def egcd(a, b):
x,y = 0,1
lx,ly = 1,0
while b != 0:
q = a/b
(a, b) = (b, a%b)
(lx, x) = (x, lx-q*x)
(ly, y) = (y, ly-q*y)
return (lx, ly)
p=7
q=11
m=p*q
(lx, ly) = egcd(p,q)
print lx*p%m,ly*q%m

calculate x ^ (1 / y) mod m fast (modular root)

How can I solve x ^ ( 1 / y ) mod m fast, where x, y, m are all positive integers?
This is to reverse the calculation for x ^ y mod m. For example
party A hands party B agree on positive integer y and m ahead of time
party A generates a number x1 (0 < x1 < m), and hands party B the result of x1 ^ y mod m, call it x2
party B calculates x2 ^ ( 1 / y ) mod m, so that it gets back x1
I know how to calculate x1 ^ y mod m fast, but I don't know how to calculate x2 ^ (1 / y) mod m fast. Any suggestions?
I don't know how to call this question. Given x ^ y mod m is called modular exponentiation, is this called modular root?
I think you're asking this question: Given y, m, and the result of x^y (mod m) find x (assuming 0 <= x < m).
In general, this doesn't have a solution -- for example, for y=2, m=4, 0^2, 1^2, 2^2, 3^2 = 0, 1, 0, 1 (mod 4), so if you're given the square of a number mod 4, you can't get back the original number.
However, in some cases you can do it. For example, when m is prime and y is coprime to m-1. Then one can find y' such that for all 0 <= x < m, (x^y)^y' = x (mod m).
Note that (x^y)^y' = x^(yy'). Ignoring the trivial case when x=0, if m is prime Fermat's Little Theorem tells us that x^(m-1) = 1 (mod m). Thus we can solve yy' = 1 (mod m-1). This has a solution (which can be found using the extended Euclidean algorithm) assuming y and m-1 are coprime.
Here's working code, with an example with y=5, m=17. It uses the modular inverse code from https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm
def egcd(a, b):
if a == 0: return b, 0, 1
g, x, y = egcd(b%a, a)
return g, y - (b//a) * x, x
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise AssertionError('no inverse')
return x % m
def encrypt(xs, y, m):
return [pow(x, y, m) for x in xs]
def decrypt(xs, y, m):
y2 = modinv(y, m-1)
return encrypt(xs, y2, m)
y = 5
m = 17
e = encrypt(range(m), y, m)
print decrypt(e, y, m)
RSA is based on the case when m is the product of two distinct primes p, q. The same ideas as above apply, but one needs to find y' such that yy' = 1 (mod lcm((p-1)(q-1))). Unlike above, one can't do this easily only given y and m, because there are no known efficient methods for finding p and q.

Write a loop invariant for partial correctness of Hoare Triple

I am new to the world of logic. I am learning Hoare Logic and Partial & Total correctness of programs. I tried alot to solve the below question but failed.
Write a loop invariant P to show partial correctness for the Hoare triple
{x = ¬x ∧ y = ¬y ∧ x >= 0} mult {z = ¬x * ¬y}
where mult is the following program that computes the product of x and y and stores it in z:
mult:
z := 0;
while (y > 0) do
z := z + x;
y := y - 1;
One of my friend gave me the following answer but I don't know if it correct or not.
Invariant P is (¬x * ¬y = z + ¬x * y) ∧ x = ¬x. Intuitively, z holds the part of the result that is already computed, and (¬x * y) is what remains to compute.
Please teach me step by step of how to solve this question.

Lazy Evaluation Correctness and Totality (Coq)

As the title suggests, my question concerns proving the correctness and totality of lazy evaluation of arithmetic expressions in Coq. The theorems that I would like to prove are three in total:
Computations only give canonical
expressions as results
Theorem Only_canonical_results:
(forall x y: Aexp, Comp x y -> Canonical y).
Correctness: the computation relation
preserves denotation of expressions
Theorem correct_wrt_semantics:
(forall x y: Aexp, Comp x y ->
I N (denotation x) (denotation y)).
Every input leads to some result.
Theorem Comp_is_total: (forall x:Aexp,
(Sigma Aexp (fun y =>
prod (Comp x y) (Canonical y)))).
The necessary definitions are to be found in the code attached below. I should make it clear I am a novice when it comes to Coq; which more experienced users will probably notice right away. It is most certainly the case that the majority, or perhaps even all of the background material I have written can be found in the standard library. But, then again, if I knew exactly what to import from the standard library in order to prove the desired results, I would most probably not be here bothering you. That is why I submit to you the material I have so far, in the hope that some kind spirited person/s may help me. Thanks!
(* Sigma types *)
Inductive Sigma (A:Set)(B:A -> Set) :Set :=
Spair: forall a:A, forall b : B a,Sigma A B.
Definition E (A:Set)(B:A -> Set)
(C: Sigma A B -> Set)
(c: Sigma A B)
(d: (forall x:A, forall y:B x,
C (Spair A B x y))): C c :=
match c as c0 return (C c0) with
| Spair a b => d a b
end.
Definition project1 (A:Set)(B:A -> Set)(c: Sigma A B):=
E A B (fun z => A) c (fun x y => x).
(* Binary sum type *)
Inductive sum' (A B:Set):Set :=
inl': A -> sum' A B | inr': B -> sum' A B.
Print sum'_rect.
Definition D (A B : Set)(C: sum' A B -> Set)
(c: sum' A B)
(d: (forall x:A, C (inl' A B x)))
(e: (forall y:B, C (inr' A B y))): C c :=
match c as c0 return C c0 with
| inl' x => d x
| inr' y => e y
end.
(* Three useful finite sets *)
Inductive N_0: Set :=.
Definition R_0
(C:N_0 -> Set)
(c: N_0): C c :=
match c as c0 return (C c0) with
end.
Inductive N_1: Set := zero_1:N_1.
Definition R_1
(C:N_1 -> Set)
(c: N_1)
(d_zero: C zero_1): C c :=
match c as c0 return (C c0) with
| zero_1 => d_zero
end.
Inductive N_2: Set := zero_2:N_2 | one_2:N_2.
Definition R_2
(C:N_2 -> Set)
(c: N_2)
(d_zero: C zero_2)
(d_one: C one_2): C c :=
match c as c0 return (C c0) with
| zero_2 => d_zero
| one_2 => d_one
end.
(* Natural numbers *)
Inductive N:Set :=
zero: N | succ : N -> N.
Print N.
Print N_rect.
Definition R
(C:N -> Set)
(d: C zero)
(e: (forall x:N, C x -> C (succ x))):
(forall n:N, C n) :=
fix F (n: N): C n :=
match n as n0 return (C n0) with
| zero => d
| succ n0 => e n0 (F n0)
end.
(* Boolean to truth-value converter *)
Definition Tr (c:N_2) : Set :=
match c as c0 with
| zero_2 => N_0
| one_2 => N_1
end.
(* Identity type *)
Inductive I (A: Set)(x: A) : A -> Set :=
r : I A x x.
Print I_rect.
Theorem J
(A:Set)
(C: (forall x y:A,
forall z: I A x y, Set))
(d: (forall x:A, C x x (r A x)))
(a:A)(b:A)(c:I A a b): C a b c.
induction c.
apply d.
Defined.
(* functions are extensional wrt
identity types *)
Theorem I_I_extensionality (A B: Set)(f: A -> B):
(forall x y:A, I A x y -> I B (f x) (f y)).
Proof.
intros x y P.
induction P.
apply r.
Defined.
(* addition *)
Definition add (m n:N) : N
:= R (fun z=> N) m (fun x y => succ y) n.
(* multiplication *)
Definition mul (m n:N) : N
:= R (fun z=> N) zero (fun x y => add y m) n.
(* Axioms of Peano verified *)
Theorem P1a: (forall x: N, I N (add x zero) x).
intro x.
(* force use of definitional equality
by applying reflexivity *)
apply r.
Defined.
Theorem P1b: (forall x y: N,
I N (add x (succ y)) (succ (add x y))).
intros.
apply r.
Defined.
Theorem P2a: (forall x: N, I N (mul x zero) zero).
intros.
apply r.
Defined.
Theorem P2b: (forall x y: N,
I N (mul x (succ y)) (add (mul x y) x)).
intros.
apply r.
Defined.
Definition pd (n: N): N :=
R (fun _=> N) zero (fun x y=> x) n.
(* alternatively
Definition pd (x: N): N :=
match x as x0 with
| zero => zero
| succ n0 => n0
end.
*)
Theorem P3: (forall x y:N,
I N (succ x) (succ y) -> I N x y).
intros x y p.
apply (I_I_extensionality N N pd (succ x) (succ y)).
apply p.
Defined.
Definition not (A:Set): Set:= (A -> N_0).
Definition isnonzero (n: N): N_2:=
R (fun _ => N_2) zero_2 (fun x y => one_2) n.
Theorem P4 : (forall x:N,
not (I N (succ x) zero)).
intro x.
intro p.
apply (J N (fun x y z =>
Tr (isnonzero x) -> Tr (isnonzero y))
(fun x => (fun t => t)) (succ x) zero)
.
apply p.
simpl.
apply zero_1.
Defined.
Theorem P5 (P:N -> Set):
P zero -> (forall x:N, P x -> P (succ x))
-> (forall x:N, P x).
intros base step n.
apply R.
apply base.
apply step.
Defined.
(* I(A,-,-) is an equivalence relation *)
Lemma Ireflexive (A:Set): (forall x:A, I A x x).
intro x.
apply r.
Defined.
Lemma Isymmetric (A:Set): (forall x y:A, I A x y -> I A y x).
intros x y P.
induction P.
apply r.
Defined.
Lemma Itransitive (A:Set):
(forall x y z:A, I A x y -> I A y z -> I A x z).
intros x y z P Q.
induction P.
assumption.
Defined.
Definition or (A B : Set):= sum' A B.
(* arithmetical expressions *)
Inductive Aexp :Set :=
zer: Aexp
| suc: Aexp -> Aexp
| pls: Aexp -> Aexp -> Aexp.
(* denotation of an expression *)
Definition denotation: Aexp->N:=
fix F (a: Aexp): N :=
match a as a0 with
| zer => zero
| suc a1 => succ (F a1)
| pls a1 a2 => add (F a1) (F a2)
end.
(* predicate for distinguishing
canonical expressions *)
Definition Canonical (x:Aexp):Set :=
or (I Aexp x zer)
(Sigma Aexp (fun y =>
I Aexp x (suc y))).
(* the computation relation is
an inductively defined relation *)
Inductive Comp : Aexp -> Aexp -> Set
:=
refrule: forall a: Aexp,
forall p: Canonical a, Comp a a
| zerrule: forall a b c:Aexp,
forall p: Comp b zer,
forall q: Comp a c,
Comp (pls a b) c
| sucrule: forall a b c:Aexp,
forall p: Comp b (suc c),
Comp (pls a b) (suc (pls a c)).
(* Computations only give canonical
expressions as results *)
Theorem Only_canonical_results:
(forall x y: Aexp, Comp x y -> Canonical y).
admit.
Defined.
(* Here is where help is needed *)
(* Correctness: the computation relation
preserves denotation of expressions *)
Theorem correct_wrt_semantics:
(forall x y: Aexp, Comp x y ->
I N (denotation x) (denotation y)).
admit.
(* Here is where help is need*)
Defined.
(* every input leads to some result *)
Theorem Comp_is_total: (forall x:Aexp,
(Sigma Aexp (fun y =>
prod (Comp x y) (Canonical y)))).
admit.
(* Proof required *)
Defined.
The first two theorems can be proved almost blindly. They follow by induction on the definition of Comp. The third one requires some thinking and some auxiliary theorems though. But you should be following a tutorial if you want to learn Coq.
About the tactics I used:
induction 1 does induction on the first unnamed hypothesis.
info_eauto tries to finish a goal by blindly applying theorems.
Hint Constructors adds the constructors of an inductive definition to the database of theorems info_eauto can use.
unfold, simpl, and rewrite should be self-explanatory.
.
Hint Constructors sum' prod Sigma I Comp.
Theorem Only_canonical_results:
(forall x y: Aexp, Comp x y -> Canonical y).
unfold Canonical, or.
induction 1.
info_eauto.
info_eauto.
info_eauto.
Defined.
Theorem correct_wrt_semantics:
(forall x y: Aexp, Comp x y ->
I N (denotation x) (denotation y)).
induction 1.
info_eauto.
simpl. rewrite IHComp1. rewrite IHComp2. simpl. info_eauto.
simpl. rewrite IHComp. simpl. info_eauto.
Defined.
Theorem Comp_is_total: (forall x:Aexp,
(Sigma Aexp (fun y =>
prod (Comp x y) (Canonical y)))).
unfold Canonical, or.
induction x.
eapply Spair. eapply pair.
eapply refrule. unfold Canonical, or. info_eauto.
info_eauto.
Admitted.

Lambda calculus help

So i'm totally stuck on this one part of a problem. It would be awesome if someone could help.........
Show that the term ZZ where Z is λz.λx. x(z z x) satisfies
the requirement for fixed point combinators that ZZM =β M(ZZM).
This is completely trivial.
You just apply the definition of β-reduction two times:
Z Z M = (λz.λx. x(z z x)) Z M > (λx. x(Z Z x)) M > M (Z Z M)
where > is the β-reduction.
Therefore Z Z M β-reduces to M (Z Z M) in two steps, hence Z Z M =β M (Z Z M).

Resources