Formalizing time and space complexity requirements - coq

∀ a b ∈ ℕ, b ≠ 0 → ∃ ! q r ∈ ℕ, a = q × b + r ∧ r < b is a standard example of the use of dependent types. How do I extend this type so that it also expresses time and space complexity requirements?

Nils Anders Danielsson uses a monad in Agda to track time complexity: sub-computations which are "relevant" to the complexity being studied are explicitly marked as such by making each of them take "one tick of time". These sub-computations are then combined monadically by tracking the sum number of ticks in the index of the monad type.
The details are described in his paper Lightweight Semiformal Time Complexity Analysis for Purely Functional Data Structures.

Related

Searching for a counterexample to a decidable predicate

It feels like the following Coq statement should be true constructively:
Require Import Decidable.
Lemma dec_search_nat_counterexample (P : nat -> Prop) (decH : forall i, decidable (P i))
: (~ (forall i, P i)) -> exists i, ~ P i.
If there were an upper bound, I'd expect to be able to show something of the form "suppose that not every i < N satisfies P i. Then there is an i < N where ~ P i". Indeed, you could actually write a function to find a minimal example by searching from zero.
Of course, there's not an upper bound for the original claim, but I feel like there should be an inductive argument to get there from the bounded version above. But I'm not clever enough to figure out how! Am I missing a clever trick? Or is there a fundamental reason that this cann't work, despite the well-orderedness of the natural numbers?
Reworked answer after Meven Lennon-Bertrand's comment
This statement is equivalent to Markov's principle with P and ~P exchanged. Since P is decidable we have P <-> (~ ~ P), so that one can do this replacement.
This paper (http://pauillac.inria.fr/~herbelin/articles/lics-Her10-markov.pdf) suggest that Markov's principle is not provable in Coq, since the author (one of the authors of Coq) suggests a new logic in this paper which allows to prove Markov's principle.
Old answer:
This is morally the "Limited Principle of Omniscience" - LPO (see https://en.wikipedia.org/wiki/Limited_principle_of_omniscience). It requires classical axioms to prove it in Coq - or you assert itself as an axiom.
See e.g.:
Require Import Coquelicot.Markov.
Check LPO.
Print Assumptions LPO.
Afair there is no standard library version of it.

Proof for pumping Lemma linear context free language

Where can I find the proof for the linear context free languages pumping lemma?
I am looking for the proof that is specific for the linear context free language
I also looked for the formal prof and could not find one.Not sure if the below is a formal prof but it may give you some idea.
The lemma : For every linear context free languages L there is an n>0 so that for every w in L with |w| > n we can write w as uvxyz such that |vy|> 0,|uvyz| <= n and uv^ixy^iz for every i>= 0 is in L.
"Proof":
Imagine a parse tree for some long string w in L with a start symbol S. Also lets assume that the tree does not contains non useful nodes. If w is long enough, there will be at least one non terminal repeating more than once. Lets call the first repeating non terminal going down the tree X, its first occurrence (from the top) as X[1] and its second occurrence as X[2].Let x be the string in w generated by X[2], vxy the string generated by X[1]and uvxyz the full string w generated by S. Since the movement from X[1] to X[2] generates v,y we could theoretically generate a new tree where we replicate this move multiple times before moving from X[1] down.This proves that uv^ixy^iz for every i>= 0 is in L. Since our tree contains no useless nodes, moving from X[1] to X[2] must generate some terminals and this proves that |vy|> 0.L is linear which means that on every level of the tree we have a single non terminal symbol. Each node in the tree covers some substring in w that its length is bounded by a linear function of the node height. Moving from S to X[2] covers uv and yz from w and the number of tree levels traveled is bounded by (2 * the number of non-terminals symbols + 1). Since the number of levels traveled is bounded and the tree is linear it also puts a bound on the yield of the movement from S to X[2] which means ,|uvyz| <= n for some n >= 0.
Note: Keep in mind that we construct X[1] , X[2] top down , in contradiction to how we prove the “regular” pumping lemma for context free grammar in general. In the "regular” pumping lemma there is a bound on the height of X[1] and therefore a bound on |vxy|. In our case there is no bound on the height of X[1]and it can be as high as required by the length of w. There is a bound,however,on the number of tree levels from S to X[2].This does not means much if the grammar is not linear as the output going from S to X[2] is still bounded only by the high of S (that is unbounded). But in the linear case,this output is bounded and therefore |uvyz| <= n

How to perform induction over two inductive predicates?

I am starting with Coq and trying to formalize Automated Amortised Analysis. I am at lemma 4.13:
Lemma preservation : forall (Sigma : prog_sig) (Gamma : context) (p : program)
(s : stack) (h h' : heap) (e : expr) (c : type0) (v : val),
(* 4.1 *) has_type Sigma Gamma e c ->
(* 4.2 *) eval p s h e v h' ->
(* 4.3 *) mem_consistant_stack h s Gamma ->
(* 4.a *) mem_consistant h' v c /\ (* 4.b *) mem_consistant_stack h' s Gamma.
Proof.
intros Sigma Gamma p s h h' e c v WELL_TYPED EVAL.
The manual proof uses a double induction:
Proof. Note that claim (4.b) follows directly by Lemma 4.8 and Lemma
4.12. Each location l ∈ dom( H ) is either left unaltered or is overwritten by the value Bad and hence does not invalidate memory
consistency.
However, the first claim (4.a) requires a proof by
induction on the lengths of the derivations of (4.2) and (4.1) ordered
lexicographically with the derivation of the evaluation taking
priority over the typing derivation. This is required since an in-
duction on the length of the typing derivation alone would fail for
the case of function application: in order to allow recursive
functions, the type rule for application is a terminal rule relying on
the type given for the function in the program’s signature. However,
proving this case requires induction on the statement that the body of
the function is well-typed, which is most certainly a type derivation
of a longer length (i.e. longer than one step), prohibiting us from
using the induction hypothesis. Note in this particular case that the
length of the derivation for the evaluation statement does decrease.
An induction over the length of the derivation for premise (4.2) alone
fails similarly. Consider the last step in the derivation of premise
(4.1) being derived by the application of a structural rule, then the
length of the derivation for (4.2) remains exactly the same, while the
length of the derivation for premise (4.1) does decrease by one step.
Using induction on the lexicographically ordered lengths of the type
and evaluation derivations allows us to use the induction hypothesis
if either the length of the deriva- tion for premise (4.2) is
shortened or if the length of the derivation for premise (4.2) remains
unchanged while the length of the typing derivation is reduced. We
first treat the cases where the last step in the typing derivation was
obtained by application of a structural rule, which are all the cases
which leave the length of the derivation for the evaluation unchanged.
We then continue to consider the remaining cases based
604.3 Operational Semantics on the evaluation rule that had been applied last to derive premise (4.2), since the remaining type rules
are all syntax directed and thus unambiguously determined by the
applied evaluation rule.
How can such a "double induction" be performed in Coq?
I tried induction EVAL; induction WELL_TYPED, but got 418 subgoals, most of wich are unprovable.
I also tried to start with induction EVAL and use induction WELL_TYPED later, but go stucked in a similar situation.
I agree with #jbapple that a minimal example is better. That said, it may be that you are simply missing a concept of length of derivation. Note that the usual concept of proof by induction over a predicate actually implements something that is close to induction over the height of derivations, but not quite.
I propose that you exhibit two new predicates eval_n and
has_type_n that each express the same as eval
and has_type, but with an extra argument with meaning "... and derivation has size n". There are several ways in which size might be defined but I suspect that height will be enough for you.
Then you can prove
eval a1 .. ak <-> exists n, eval_n a1 .. ak n
and
has_type a1 .. ak <-> exists n, has_type a1 .. ak n
You should then be able to prove
forall p : nat * nat, forall a1 ... ak, eval_n a1 .. ak (fst p) ->
has_type_n a1 .. ak (snd p) -> YOUR GOAL
by well founded induction on pairs of natural numbers, using the lexical order construction of library Wellfounded (I suggest library Lexicographic_Product.v, it is a bit of an overkill for just pairs of natural numbers, but you only need to find the right instantiation).
This will be unwieldy because induction hypotheses will only refer to pairs
of numbers that are comparable for the lexical order, and you will have to perform inversions on the hypotheses concerning eval_n and has_type_n, but that should go through.
There probably exists a simpler solution, but for lack of more information from your side, I can only propose the big gun.

How is "less than" defined for real numbers in Coq?

I am just wondering how is the "less than" relationship defined for real numbers.
I understand that for natural numbers (nat), < can be defined recursively in terms of one number being the (1+) successor S of another number. I heard that many things about real numbers are axiomatic in Coq and do not compute.
But I am wondering whether there is a minimum set of axioms for real numbers in Coq based upon which other properties/relations can be derived. (e.g. Coq.Reals.RIneq has it that Rplus_0_r : forall r, r + 0 = r. is an axiom, among others)
In particular, I am interested in whether the relationships such as < or <= can be defined on top of the equality relationship. For example, I can imagine that in conventional math, given two numbers r1 r2:
r1 < r2 <=> exists s, s > 0 /\ r1 + s = r2.
But does this hold in the constructive logic of Coq? And can I use this to at least do some reasoning about inequalities (instead of rewriting axioms all the time)?
Coq.Reals.RIneq has it that Rplus_0_r : forall r, r + 0 = r. is an axiom, among others
Nitpick: Rplus_0_r is not an axiom but Rplus_0_l is. You can get a list of them in the module Coq.Reals.Raxioms and a list of the parameters used in Coq.Reals.Rdefinitions.
As you can see "greater than (or equal)" and "less than or equal" are all defined in terms of "less than" which is postulated rather than introduced using the proposition you suggest.
It looks like Rlt could indeed be defined in the fashion you suggest: the two propositions are provably equivalent as shown below.
Require Import Reals.
Require Import Psatz.
Open Scope R_scope.
Goal forall (r1 r2 : R), r1 < r2 <-> exists s, s > 0 /\ r1 + s = r2.
Proof.
intros r1 r2; split.
- intros H; exists (r2 - r1); split; [lra | ring].
- intros [s [s_pos eq]]; lra.
Qed.
However you would still need to define what it means to be "strictly positive" for the s > 0 bit to make sense and it's not at all clear that you'd have fewer axioms in the end (e.g. the notion of being strictly positive should be closed under addition, multiplication, etc.).
Indeed, the Coq.Real library is a bit weak in the sense that it is totally specified as axioms, and at some (brief) points in the past it was even inconsistent.
So the definition of le is a bit "ad hoc" in the sense that from the point of view of the system it carries zero computational meaning, being just a constant and a few axioms. You could well add the axiom "x < x" and Coq could do nothing to detect it.
It is worth pointing to some alternative constructions of the Reals for Coq:
My favourite classical construction is the one done in the four Color theorem by Georges Gonthier and B. Werner: http://research.microsoft.com/en-us/downloads/5464e7b1-bd58-4f7c-bfe1-5d3b32d42e6d/
It only uses the excluded middle axiom (mainly to compare real numbers) so the confidence in its consistency is very high.
The best known axiom-free characterization of the reals is the C-CORN project, http://corn.cs.ru.nl/ but we aware that constructive analysis significantly differs from the usual one.

What forms of goal in Coq are considered to be "true"?

When I prove some theorem, my goal evolves as I apply more and more tactics. Generally speaking the goal tends to split into sub goals, where the subgoals are more simple. At some final point Coq decides that the goal is proven. How this "proven" goal may look like? These goals seems to be fine:
a = a. (* Any object is identical to itself (?) *)
myFunc x y = myFunc x y. (* Result of the same function with the same params
is always the same (?) *)
What else can be here or can it be that examples are fundamentally wrong?
In other words, when I finally apply reflexivity, Coq just says ** Got it ** without any explanation. Is there any way to get more details on what it actually did or why it decided that the goal is proven?
You're actually facing a very general notion that seems not so general because Coq has some user-friendly facility for reasoning with equality in particular.
In general, Coq accepts a goal as solved as soon as it receives a term whose type is the type of the goal: it has been convinced the proposition is true because it has been convinced the type that this proposition describes is inhabited, and what convinced it is the actual witness you helped build along your proof.
For the particular case of inductive datatypes, the two ways you are going to be able to proved the proposition P a b c are:
by constructing a term of type P a b c, using the constructors of the inductive type P, and providing all the necessary arguments.
or by reusing an existing proof or an axiom in the environment whose type you can get to match P a b c.
For the even more particular case of equality proofs (equality is just an inductive datatype in Coq), the same two ways I list above degenerate to this:
the only constructor of equality is eq_refl, and to apply it you need to show that the two sides are judgementally equal. For most purposes, this corresponds to goals that look like T a b c = T a b c, but it is actually a slightly more broad notion of equality (see below). For these, all you have to do is apply the eq_refl constructor. In a nutshell, that is what reflexivity does!
the second case consists in proving that the equality holds because you have other equalities in your context, nothing special here.
Now one part of your question was: when does Coq accept that two sides of an equality are equal by reflexivity?
If I am not mistaken, the answer is when the two sides of the equality are αβδιζ-convertible.
What this grossly means is that there is a way to make them syntactically equal by repeated applications of:
α : sane renaming of non-free variables
β : computing reducible expressions
δ : unfolding definitions
ι : simplifying matches
ζ : expanding let-bound expressions
[someone please correct me if more rules apply or if I got one wrong]
For instance some of the things that are not captured by these rules are:
equality of functions that do more or less the same thing in different ways:
(fun x => 0 + x) = (fun x => x + 0)
quicksort = mergesort
equality of terms that are stuck reducing but would be equal:
forall n, 0 + n = n + 0