Proving that two strings are different in Lean - lean

As I was carrying out my normal course of lean theorem proving, I realized my current file
was taking an awfully long time to compile. I then narrowed down the issue to the
part where I was attempting to prove that two strings were distinct:
lemma L0 : "x" ≠ "y" :=
begin
intros H, cases H
end
This little lemma alone will take 15 seconds to compile on my (albeit) slow machine.
something is seriously wrong.
I am not a fluent Lean user so guessing I should not be using the cases tactic for string. What else can I do?
The corresponding lemma in Coq works fine without any timing issue:
Require Import String.
Open Scope string_scope.
Lemma L0 : "x" <> "y".
Proof.
intros H. inversion H.
Qed.

dec_trivial works pretty quickly for me.
lemma L0 : "x" ≠ "y" := dec_trivial

Related

erase common constant of equation using leanprover

I want to prove below goal.
n_n: ℕ
n_ih: n_n * (n_n + 1) / 2 = arith_sum n_n
⊢ (n_n + 1) * (n_n + 1 + 1) / 2 = n_n + 1 + n_n * (n_n + 1) / 2
ring, simp, linarith is not working.
Also I tried calc, but it too long.
Is there any automatic command to erase common constant in equation?
I would say that you were asking the wrong question. Your hypothesis and goal contain / but this is not mathematical division, this is a pathological function which computer scientists use, which takes as input two natural numbers and is forced to return a natural number, so often can't return the right answer. For example 5 / 2 = 2 with the division you're using. Computer scientists call it "division with remainder" and I call it "broken and should never be used". When I'm doing this sort of exercise with my class I always coerce everything to the rationals before I do the division, so the division is mathematical division rather than this pathological function which does not satisfy things like (a / b) * b = a. The fact that this division doesn't obey the rules of normal division is why you can't get the tactics to work. If you coerce everything to the rationals before doing the division then you won't get into this mess and ring will work fine.
If you do want to persevere down the natural division road then one approach would be to start doing things proving that n(n+1) is always even, so that you can deduce n(n+1)/2)*2=n(n+1). Alternatively you could avoid this by observing that to show A/2=B/2 it suffices to prove that A=B. But either way you'll have to do a few lines of manual fiddling because you're not using mathematical functions, you're using computer science approximations, so mathematical tactics don't work with them.
Here's what my approach looks like:
import algebra.big_operators
open_locale big_operators
open finset
def arith_sum (n : ℕ) := ∑ i in range n, (i : ℚ) -- answer is rational
example (n : ℕ) : arith_sum n = n*(n-1)/2 :=
begin
unfold arith_sum,
induction n with d hd,
{ simp },
{ rw [finset.sum_range_succ, hd, nat.succ_eq_add_one],
push_cast,
ring, -- works now
}
end

In coq, how to make proofs involving summations and means?

For example, how to proof in coq that:
or that:
You have many ways to state your lemmas and definitions, in particular it depends what your assumptions over the datatypes are. I recommend using the bigop library from the Mathematical Components Coq package. With it, you can prove your second lemma easily enough:
From mathcomp Require Import all_ssreflect all_algebra.
Section Avg.
Open Scope ring_scope.
Import GRing.Theory.
Variables (N : fieldType) (n : nat) (n_pos : n%:R != 0 :> N) (X : n.-tuple N).
Definition avg := (\sum_(x <- X) x) / n%:R.
Lemma avgP : \sum_(x <- X) (x - avg) = 0.
Proof.
rewrite sumrB !big_tuple sumr_const card_ord -mulr_natr divfK //.
by rewrite big_tuple subrr.
Qed.
End Avg.
Note that the above code is just meant as an example for you to get a feeling of a simple proof; properly developing a theory about statistic would require way more though and likely a different encoding of avg.

Proof a language is not regular using Pumping Lemma

I am trying to prove that the following language is not regular using the pumping lemma.
L = {ak b3l al | k ≥ 1 , l ≥ 0}
I have decided to choose w = a b3p ap, then |w| = 4p+1 ≥ p
Any tips?
Thank you!
I am not sure about the exact formulation of the pumping lemma that you are using. At any rate, this is a rather tricky case, because standard formulations like in wikipedia only let you pump somewhere in a prefix of fixed length. But your initial block of a allows pumping anywhere and can be arbitrarily long. Thus you have to use some additional property. I suggest two:
Regular languages are closed under reversal. Thus you may as well look at $L^R = {a^l b^{3l} a^k}$. Now any pumping in the initial block of a will lead out of the language.
Regular languages are closed under intersection. If you take the intersection with a b+ a+ you end up with ${a b^{3l} a^k}$, and now pumping in the b block will take you out of the language.

Proof of reverse binary strings?

If w : {1...L} → {0,1} is a binary string, the complement of w, denoted wC, is a string of length L defined by: wc(i) = 1 - w(i). The reverse of w, denoted wR, is the string of the length L defined by wR(i) = w(L + 1 - i). Use these definitions to give careful proof that, for every binary string x, (xC)R = (xR)C.
I have no idea how to start this question. I don't really want a direct answer I'd like to learn how to do this question by induction for future questions
If the solution I see is the simplest one, then it's a quite comprehensive exercise.
I suggest you start by proving a the following lemmas:
Lemma 1: (w0)C=(wC)1
Lemma 2: (w0)R=0(wR)
Both Lemma 1 and 2 can be proven by induction on the length of w. Doing it strictly by the given rules is tedious, but not very hard.
Argue that the following lemmas hold as well by the same argument
Lemma 1b: (w1)C=wC0
Lemma 2b: (w1)R=1(wR)
With those lemmas in place, you should be able to tackle the original problem of showing (xC)R=(xR)C.
Do an induction over L (i.e. the length of the word). The base case should be trivial. In the inductive step you'll end up with something like
Induction hypothesis
(uC)R=(uR)C.
Left to show:
((u0)C)R=((u0)R)C
and (by analogy)
((u1)C)R=((u1)R)C
Solving this step will involve the lemmas above.

Using Closure Properties to prove Regularity

Here's a homework problem:
Is L_4 Regular?
Let L_4 = L*, where L={0^i1^i | i>=1}.
I know L is non-regular and I know that Kleene Star is a closed operation, so my assumption is that L_4 is non-regular.
However my professor provided an example of the above in which L = {0^p | p is prime}, which he said was regular by proving that L* was equal to L(000* + e) by saying each was a subset of one another (e in this case means the empty word).
So his method involved forming a regex of 0^p, but how I can do that when I essentially have one already?
Regular languages are closed under Kleene star. That is, if language R is regular, so is R*.
But the reasoning doesn't work in the other direction: there are nonregular languages P for which P* is actually regular.
You mentioned one such P in your question: the set of strings 0^p where p is prime.
It is easy to use the pumping lemmas for regular and context-free languages to show that P is at least context-sensitive.
However, P* is equivalent to the language 0^q, where q is the sum of zero or more primes.
But this is true for q=0 (the empty string) and any q>=2, so P* can be recognized with a 3-state DFA, even though P itself is not regular.
So L being context-free has no bearing on whether your L_4 = L* is regular or not. If you can construct a DFA that recognizes L_4, as I did for P* above, then clearly it's regular.
In the process of trying to find a DFA that works, you'll probably see some pattern
emerge that can be used as the basis for a pumping argument. The Myhill-Nerode theorem is another approach to proving a language non-regular, and is useful if the language lends itself to analysis of prefixes and distinguishing extensions. If the language can be decomposed into a finite set of equivalence classes under a certain relation, then it can be recognized with a DFA containing that many states.
Edit: For anyone wondering whether OP's example L_4 is regular or not...it's not, which can be proved using the pumping lemma for regular languages.
Assume L_4 is regular, with "pumping length" P. Consider the string w=0P1P, which is an element of L_4. We need to decompose it into the form w=xyz,
with |y| >= 1 and |xy| <= P. Any choice of xy fulfilling these conditions will consist of all zeroes. But then any string w' = xynz with n != 1 will have mismatched counts of 0s and 1s, and therefore cannot be an element of L_4. So the pumping lemma does not hold, and L_4 cannot be regular.

Resources