Transition rule priority and set pattern matching in K? - kframework

With non-deterministic rules, is there a way to prioritise certain rules until they cannot be applied anymore before applying other rules?
e.g. In the following rules (in pseudocode)
1. (S U {P | Q}) => (S U {P, Q}) [prioritise]
2. (S U {P + Q}) => (S U {P}) [transition]
3. (S U {P + Q}) => (S U {Q}) [transition]
the intention is to prioritise non-deterministic structural rules such as (1) before non-deterministically applying rules (2) and (3). i.e. if negative pattern-matching is allowed, only apply (2) and (3) if nothing in S is of the form P|Q. If I'm not mistaken, I could achieve a similar effect using functions, but I was wondering if there is more direct way.
Also, somewhat related to the rules above, is the following the correct syntax to find multiple elements of the form A + _?
<myset> ... SetItem(A + B) SetItem(A + C)... </myset>
Is it possible to update them then?
<myset> ... (SetItem(A + B)=>SetItem(B)) (SetItem(A + C)=>SetItem(C))... </myset>

Just to make sure, the transition attribute is deprecated, so does not mean anything on the modern K backends.
We do support exactly what you need via the priority(...) attribute. You can do:
rule [one]: (S U {P | Q}) => (S U {P, Q}) [priority(25)]
rule [two]: (S U {P + Q}) => (S U {P}) [priority(26)]
rule [three]: (S U {P + Q}) => (S U {Q}) [priority(26)]
This will ensure that rule one is always tried before rules two or three are tried. This works on both the LLVM (concrete execution) and Haskell (symbolic execution) backends, and it works for both normal rules and function rules. Note that because the Haskell backend must do an exhaustive search through the state-space, if it cannot prove that a lower priority rule covers all possible behaviors, it will still try higher priority rules on the remainder that is not covered by the lower priority rules.
Priorities can be between 0 and 200 (inclusive).
You can also use the owise attribute, which is basically a synonym for priority(200).
The default priority of most rules is 50. Some specific automatically generated rules get priority 100.

Related

Pointwise function equality proof [duplicate]

I'm just starting playing with idris and theorem proving in general. I can follow most of the examples of proofs of basic facts on the internet, so I wanted to try something arbitrary by my own. So, I want to write a proof term for the following basic property of map:
map : (a -> b) -> List a -> List b
prf : map id = id
Intuitively, I can imagine how the proof should work: Take an arbitrary list l and analyze the possibilities for map id l. When l is empty, it's obvious; when
l is non-empty it's based on the concept that function application preserves equality.
So, I can do something like this:
prf' : (l : List a) -> map id l = id l
It's like a for all statement. How can I turn it into a proof of the equality of the functions involved?
You can't. Idris's type theory (like Coq's and Agda's) does not support general extensionality. Given two functions f and g that "act the same", you will never be able to prove Not (f = g), but you will only be able to prove f = g if f and g are defined the same, up to alpha and eta equivalence or so. Unfortunately, things only get worse when you consider higher-order functions; there's a theorem about such in the Coq standard library, but I can't seem to find or remember it right now.

In Lean, is it possible to use decidable_linear_order with a user defined equality relation?

Lean comes with a decidable_linear_order typeclass containing useful lemmas about an ordering and its relation to equality, such as:
lemma eq_or_lt_of_not_lt [decidable_linear_order α] {a b : α} (h : ¬ a < b) : a = b ∨ b < a
The equalities in these orderings are all expressed in terms of =:
inductive eq {α : Sort u} (a : α) : α → Prop
| refl : eq a
I was wondering whether it would be possible to somehow extend this class (and its superclasses) to work with an arbitrary used defined equality relation R: α → α → Prop that was reflexive, symmetric and transitive, or would this only be possible by rewriting all the relevant lemmas and their proofs to use R instead of eq?
Since these classes are not parameterized by the equality relation, you would indeed have to reimplement them (perhaps metaprogramming may be of help for that). Alternatively, because you have an equivalence relation, you could define your order on the quotient type and so keep using eq.

Well typed and ill typed lambda terms

I have been trying to understand the applied lambda calculus. Up till now, I have understood how type inference works. But I am not able to follow what is the meaning of saying that a term is well-typed or ill-typed and then how can I determine whether a given term is well-typed or ill-typed.
For example, consider a lambda term tw defined as λx[(x x)] . How to conclude whether it is a well-typed or ill-typed term?
If we are talking about Simply Typed Lambda Calculus with some additional constants and basic types (i.e. applied lambda calculus), then the term λx:σ. (x x) is well-formed, but ill-typed.
'Well-formed' means syntactically correct, i.e. will be accepted by a parser for STLC. 'Ill-typed' means the type-checker would not pass it further.
Type-checker works according to the typing rules, which are usually expressed as a number of typing judgements (one typing scheme for each syntactic form).
Let me show that the term you provided is indeed ill-typed.
According to the rule (3) [see the typing rules link], λx:σ. (x x) must have type of general form σ -> τ (since it is a function, or more correctly abstraction). But that means the body (x x) must have some type τ (assuming x : σ). This is basically the same rule (3) expressed in a natural language. So, now we need to figure out the type of the function's body, which is an application.
Now, the rule for application (4) says that if we have an expression like this (e1 e2), then e1 must be some function e1 : α -> β and e2 : α must be an argument of the right type. Let's apply this rule to our expression for the body (x x). (1) x : α -> β and (2) x : α. Since an term in STLC can have only one type, we've got an equation: α -> β = α.
But there is no way we can unify both types together, since α is a subpart of α -> β. That's why this won't typecheck.
By the way, one of the major points of STLC was to forbid self-application (like (x x)), because it prevents from using (untyped) lambda calculus as a logic, since one can perform non-terminating calculations using self-application (see for instance Y-combinator).

Decidability of propositional equaility

Two terms in agda are said to be definitionally equal precisely when they both have the same normal form ---I think---, and propositional equality is just the data-type representation of definitional equality ---again, I guess---; so then shouldn't propositionally equality be decidable? That is, would it seem reasonable that we can write a function typed
∀{A : Set} → (x y : A) → Dec(x ≡ y).
I kinda of get that we cannot write such a function since we cannot pattern match on the arguments, but I 'feel' that it should be possible: again, just reduce to normal form and check for syntactic identity.
Any insight would be helpful!
Two terms in agda are said to be definitionally equal precisely when
they both have the same normal form
Up to αη-conversion.
and propositional equality is just the data-type representation of definitional equality
Propositional equality says "these two terms will become definitionally equal after you instantiate some free variables" ("some" can be 0 or all of them) ("instantiate" can vary too).
E.g.
double-double : (n : ℕ) -> n + n ≡ 2 * n
clearly, n + n is not syntactically equal to 2 * n, but for any canonical n (0, 1, 2...) the result of n + n is syntactically equal to the result of 2 * n — that's what double-double says. And that "for any canonical n" part forces us to prove double-double by induction (though, in a more complicated system, where definitional equality is based on supercompilation or there is a build-in prover, n + n is definitionally equal to 2 * n).
But sometimes it's not as obvious how an induction hypothesis should look like, e.g. when you need to generalize an equation. As you might expect, there is no decision procedure for "is this arbitrary thing provable?" and hence propositional equality is undecidable. Moreover, you can't neither prove nor disprove statements like
(λ n -> 1 + n) ≡ (λ n -> n + 1)
without additional postulates.
However you really can check for syntactic equality:
_≟_ : ∀ {α} {A : Set α} -> (x y : A) -> Maybe (x ≡ y)
It says "if two terms are syntactically equal, then they are equal propositionally, otherwise we don't know whether they are equal propositionally or not". But Agda doesn't have such built-in function.

How or is that possible to prove or falsify `forall (P Q : Prop), (P -> Q) -> (Q -> P) -> P = Q.` in Coq?

I want to prove or falsify forall (P Q : Prop), (P -> Q) -> (Q -> P) -> P = Q. in Coq. Here is my approach.
Inductive True2 : Prop :=
| One : True2
| Two : True2.
Lemma True_has_one : forall (t0 t1 : True), t0 = t1.
Proof.
intros.
destruct t0. destruct t1.
reflexivity.
Qed.
Lemma not_True2_has_one : (forall (t0 t1 : True2), t0 = t1) -> False.
Proof.
intros.
specialize (H One Two).
inversion H.
But, inversion H does nothing. I think maybe it's because the coq's proof independence (I'm not a native English speaker, and I don't know the exact words, please forgive my ignorance), and coq makes it impossible to prove One = Two -> False. But if so why has to coq eliminate the content of a proof?
Without the above proposition, I can't prove the followings or their negations.
Lemma True_neq_True2 : True = True2 -> False.
Theorem iff_eq : forall (P Q : Prop), (P -> Q) -> (Q -> P) -> P = Q.
So my question is:
How to or is that possible to prove or falsify forall (P Q : Prop),
(P -> Q) -> (Q -> P) -> P = Q. in Coq?
Why inversion H does nothing; does it's because the coq's proof independence, and if so, why does Coq waste energy in doing this.
The principle you're mentioning, forall P Q : Prop, (P <-> Q) -> P = Q, is usually known as propositional extensionality. This principle is not provable in Coq's logic, and originally the logic had been designed so that it could be added as an axiom with no harm. Thus, in the standard library (Coq.Logic.ClassicalFacts), one can find many theorems about this principle, relating it to other well-known logical principles of classical reasoning. Surprisingly, it was recently found out that Coq's logic is incompatible with this principle, but for a very subtle reason. This is considered a bug, since the logic had been designed so that this could be added as an axiom with no harm. They wanted to fix this problem in the new version of Coq, but I don't know what the current status of that is. As of version 8.4, propositional extensionality is inconsistent in Coq.
In any case, if this bug is fixed in future versions of Coq, it should not be possible to prove nor disprove this principle in Coq. In other words, the Coq team wants this principle to be independent of Coq's logic.
inversion H doesn't do anything there because the rules for reasoning about proofs (things whose type is a Prop) are different from the ones for reasoning about non-proofs (things whose type is a Type). You may know that proofs in Coq are just terms. Under the hood, inversion is essentially constructing the following term:
Definition true_not_false : true <> false :=
fun H =>
match H in _ = b
return if b then True else False
with
| eq_refl => I
end.
If you try to do the same with a version of bool in Prop, you get a more informative error:
Inductive Pbool : Prop :=
| Ptrue : Pbool
| Pfalse : Pbool.
Fail Definition Ptrue_not_Pfalse : Ptrue <> Pfalse :=
fun H =>
match H in _ = b
return if b then True else False
with
| eq_refl => I
end.
(* The command has indeed failed with message: *)
(* => Error: *)
(* Incorrect elimination of "b" in the inductive type "Pbool": *)
(* the return type has sort "Type" while it should be "Prop". *)
(* Elimination of an inductive object of sort Prop *)
(* is not allowed on a predicate in sort Type *)
(* because proofs can be eliminated only to build proofs. *)
Indeed, one of the reasons for this is that Coq was designed to be compatible with another principle called proof irrelevance (I think that's what you meant by "proof independence").