Locale definition produces two parse trees - parsing

Here is my simple locale definition in Isabelle:
locale sig =
fixes le:: "'a ⇒ 'a ⇒ bool" (infixl "≤" 50)
assumes refl: "x ≤ x"
Now, I get an error message:
Ambiguous input⌂ produces 2 parse trees:
("\<^const>HOL.Trueprop"
("\<^const>Orderings.ord_class.less_eq" ("_position" x) ("_position" x)))
("\<^const>HOL.Trueprop" ("\<^fixed>le" ("_position" x) ("_position" x)))
Ambiguous input
2 terms are type correct:
(x ≤ x)
(x ≤ x)
Failed to parse prop
Do I have a conflict with a builtin less-or-equal operator?
How can I fix this?

The ≤ operator is defined in the ord typeclass, so you could just extend this class:
class sig = ord +
assumes refl: "x ≤ x"
Other alternatives:
Do not import the definition of ord
Hide the existing notation with no_notation Orderings.ord_class.less_eq ("(_/ ≤ _)" [51, 51] 50) (see hiding operators to avoid ambiguities in the AST)
Use a different name or symbol

Related

What axiom makes you be able to skip definition for impossible input for function in Agda?

_/_ : (dividend divisor : ℕ) .{{_ : NonZero divisor}} → ℕ
m / (suc n) = div-helper 0 n m n
In this function definition, there is no definition of case when second input is zero, because Agda knows second input cannot be zero. But in formal(theoretical) perspective, what justify these function definition? Is there axioms like 'you can skip definition for impossible input' in Type Theory, like axiom J and axiom K?
The axiom that you need is called the "principle of explosion" or "ex falso quodlibet" (see https://en.wikipedia.org/wiki/Principle_of_explosion). In type theory, this is typically formulated as an elimination principle for the empty type:
A : Type b : ⊥
————————————————–
absurd b : A

How to recover intermediate computation results from a function using "with"?

I wrote a function on the natural numbers that uses the operator _<?_ with the with-abstraction.
open import Data.Maybe
open import Data.Nat
open import Data.Nat.Properties
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
fun : ℕ → ℕ → Maybe ℕ
fun x y with x <? y
... | yes _ = nothing
... | no _ = just y
I would like to prove that if the result of computing with fun is nothing then the original two values (x and y) fulfill x < y.
So far all my attempts fall short to prove the property:
prop : ∀ (x y)
→ fun x y ≡ nothing
→ x < y
prop x y with fun x y
... | just _ = λ()
... | nothing = λ{refl → ?} -- from-yes (x <? y)}
-- This fails because the pattern matching is incomplete,
-- but it shouldn't. There are no other cases
prop' : ∀ (x y)
→ fun x y ≡ nothing
→ x < y
prop' x y with fun x y | x <? y
... | nothing | yes x<y = λ{refl → x<y}
... | just _ | no _ = λ()
--... | _ | _ = ?
In general, I've found that working with the with-abstraction is painful. It is probably due to the fact that with and | hide some magic in the background. I would like to understand what with and | really do, but the "Technical details" currently escape my understanding. Do you know where to look for to understand how to interpret them?
Concrete solution
You need to case-split on the same element on which you case-split in your function:
prop : ∀ x y → fun x y ≡ nothing → x < y
prop x y _ with x <? y
... | yes p = p
In the older versions of Agda, you would have had to write the following:
prop-old : ∀ x y → fun x y ≡ nothing → x < y
prop-old x y _ with x <? y
prop-old _ _ refl | yes p = p
prop-old _ _ () | no _
But now you are able to completely omit a case when it leads to a direct contradiction, which is, in this case, that nothing and just smth can never be equal.
Detailed explanation
To understand how with works you first need to understand how definitional equality is used in Agda to reduce goals. Definitional equality binds a function call with its associated expression depending on the structure of its input. In Agda, this is easily seen by the use of the equal sign in the definition of the different cases of a function (although since Agda builds a tree of cases some definitional equalities might not hold in some cases, but let's forget this for now).
Let us consider the following definition of the addition over naturals:
_+_ : ℕ → ℕ → ℕ
zero + b = b
(suc a) + b = suc (a + b)
This definition provides two definitional equalities that bind zero + b with b and (suc a) + b with suc (a + b). The good thing with definitional equalities (as opposed to propositional equalities) is that Agda automatically uses them to reduce goals whenever possible. This means that, for instance, if in a further goal you have the element zero + p for any p then Agda will automatically reduce it to p.
To allow Agda to do such reduction, which is fundamental in most cases, Agda needs to know which of these two equalities can be exploited, which means a case-split on the first argument of this addition has to be made in any further proof about addition for a reduction to be possible. (Except for composite proofs based on other proofs which use such case-splits).
When using with you basically add additional definitional equalities depending on the structure of the additional element. This only makes sense, understanding that, that you need to case-split on said element when doing proofs about such a function, in order for Agda once again to be able to make use of these definitional equalities.
Let us take your example and apply this reasoning to it, first without the recent ability to omit impossible cases. You need to prove the following statement:
prop-old : ∀ x y → fun x y ≡ nothing → x < y
Introducing parameters in the context, you write the following line:
prop-old x y p = ?
Having written that line, you need to provide a proof of x < y with the elements in the context. x and y are just natural so you expect p to hold enough information for this result to be provable. But, in this case, p is just of type fun x y ≡ nothing which does not give you enough information. However, this type contains a call to function fun so there is hope ! Looking at the definition of fun, we can see that it yields two definitional equalities, which depend on the structure of x <? y. This means that adding this parameter to the proof by using with once more will allow Agda to make use of these equalities. This leads to the following code:
prop-old : ∀ x y → fun x y ≡ nothing → x < y
prop-old x y p with x <? y
prop-old _ _ p | yes q = ?
prop-old _ _ p | no q = ?
At that point, not only did Agda case-split on x <? y, but it also reduced the goal because it is able, in both cases, to use a specific definitional equality of fun. Let us take a closer look at both cases:
In the yes q case, p is now of type nothing ≡ nothing and q is of type x < y which is exactly what you want to prove, which means the goal is simply solved by:
prop-old _ _ p | yes q = q
I the no q case, something more interesting happens, which is somewhat harder to understand. After reduction, p is now of type just y ≡ nothing because Agda could use the second definitional equality of fun. Since _≡_ is a data type, it is possible to case-split on p which basically asks Agda: "Look at this data type and give me all the possible constructors for an element of type just y ≡ nothing". At first, Agda only finds one possible constructor, refl, but this constructor only builds an element of a type where both sides of the equality are the same, which is not the case here by definition because just and nothing are two distinct constructors from the same data type, Maybe. Agda then concludes that there are no possible constructors that could ever build an element of such type, hence this case is actually not possible, which leads to Agda replacing p with the empty pattern () and dismissing this case. This line is thus simply:
prop-old _ _ () | no _
In the more recent versions of Agda, as I explained earlier, some of these steps are done directly by Agda which allows us to directly omit impossible cases when the emptiness of a pattern can be deduced behind the curtain, which leads to the prettier:
prop : ∀ x y → fun x y ≡ nothing → x < y
prop x y _ with x <? y
... | yes p = p
But it is the same process, just done a bit more automatically. Hopefully, these elements will be of some use in your journey towards understanding Agda.

Haskell Parsing: x ++ y : z

In Haskell, why is x ++ y : z parsed as x ++ (y : z) and not as (x ++ y) : z?
For instance, [1] ++ 2 : [3] evaluates to [1,2,3].
Both (++) and (:) are right-associative with precedence 5.
The fact that they are right associative means that these are parsed "right-to-left" so to speak. It thus means that x ⊕ y ⊕ z is parsed as x⊕ (y ⊕ z). So that means that x ++ y : z is indeed parsed as x ++ (y : z).
There are good reasons to make both (:) and (++) right associative. For the "cons" (:) operator, it means that we can write 1 : 4 : 2 : [], since it is parsed as 1 : (4 : (2: [])), which is correct in terms of the types. If would parse it like ((1:4):2:[]), then 1:4 would for example be wrong, since it expects an item as the first operand, and list of these items as the second operand. We can of course still let the Haskell parser parse it as a list, but that would result in a large amount of extra parenthesis.
For (++) it is better to parse it right-to-left as well due to performance reasons. x ++ y takes linear time in the size of x. So that means that if we parse x ++ (y ++ z), it will take |x| + |y| steps. If we would parse this as (x ++ y) ++ z, it would take 2×|x|+|y|, since the first time we apply (x ++ y) it runs in the size of x, but then (x ++ y) ++ z runs in the size of x ++ y. This thus would mean that if we concatenate n lists each with a size of m, it will not run in O(n×m), but in O(n2×m).

Idiomatically capturing "all idempotent semirings induce a partial order"

I am trying to capture the fact that there's an induced partial ordering in any idempotent semiring in Isabelle/HOL but am having trouble working out the best/correct way to do it.
I define:
class idem_semiring_1 = semiring_1 +
assumes idem [algebra_simps]: ‹a + a = a›
begin
definition less_eq :: ‹'a ⇒ 'a ⇒ bool›
where ‹less_eq a b ⟷ a + b = b›
definition less :: ‹'a ⇒ 'a ⇒ bool›
where ‹less a b ⟷ less_eq a b ∧ ¬ less_eq b a›
end
Now, it's straightforward to demonstrate that less_eq and less satisfy all of the laws of the order type class. However, is there a way of convincing Isabelle/HOL that any instance of idem_semiring_1 is also necessarily an instance of order using these definitions, so that the following query type-checks?
term ‹(y::'a::{idem_semiring_1}) ≤ x›
No combination of subclass, sublocale, etc., incantations seems to achieve what I want. In particular, the following:
sublocale idem_semiring_1 ⊆ order less_eq less
by (standard; clarsimp simp add: algebra_simps less_eq_def less_def) (metis add.assoc)
seems to work, as in the following lemmas become trivially provable via simp:
lemma
fixes x::‹'a::{idem_semiring_1}›
shows ‹less_eq x x›
by simp
lemma
assumes ‹less_eq x y›
and ‹less_eq y z›
shows ‹less_eq x z›
using assms by simp
but the following does not type-check:
lemma
fixes x :: ‹'a::{idem_semiring_1}›
shows ‹x ≤ x›
What am I not doing to convince Isabelle to connect the ≤ syntax with the less_eq definition?
What if you defined idem_semiring_1 like this:
class idem_semiring_1 = semiring_1 + order +
assumes idem [algebra_simps]: ‹a + a = a› and
less_eq_idem_semiring_1: ‹a ≤ b ⟷ a + b = b›

How this is working in agda?

I want to prove that there exist a natural number which is less than 10. I write the code in this way..
thm2 : (∃ λ m → (m < 10))
thm2 = zero , s≤s z≤n
I am not able to understand how this is working. Please explain..
Let's dissect thm2.
The type of the expression
∃ λ m → m < 10
∃ is defined in Data.Product as an alias for Σ where the first argument is left implicit. This means that ∃ is taking an element B of type A → Set and returning the type of pairs containing an a of type A and a b of type B a.
Now, λ m → m < 10 is taking an m in ℕ and returning the type of proofs that m < 10.
So ∃ λ m → m < 10 is the type of pairs of an ℕ and a proof that it is less than 10.
The expression itself
zero , s≤s z≤n
For the whole thing to typecheck, we need:
zero to be a ℕ which it is.
s≤s z≤n to be a proof that 0 < 10. _<_ is defined in Data.Nat.Base as an alias for λ m n → suc m ≤ n. So proving that 0 < 10 is the same as proving that 1 ≤ 10.
Now, _≤_ is an inductive type with two constructors:
a base case z≤n saying that 0 is less than or equal to all natural numbers
a step case s≤s saying that if one number is less than or equal to another, then their sucs also are less than or equal.
The proof s≤s z≤n is indeed a valid proof that 1 ≤ 10: z≤n proves that 0 ≤ 9 and s≤s concludes that therefore 1 ≤ 10.

Resources