I would like to automatically case over arguments using a syntax declared
besides the one given as a type constructor. For example,
postulate P : ℕ → ℕ → Set
data Silly : Set where
goo : (n : ℕ) → Fin n → (m : ℕ) → Fin m → P n m → Silly
Here, I'd like to have the proof P n m occur between the n and m arguments, but that cannot be since both need to be declare for it to be expressed. Hence, we use a syntax declaration:
syntax goo n i m j pf = i ⟵[ n , pf , m ]⟶ j
Now, we can write-up by-hand
want-to-use-syntax-in-pattern-matching : Silly → Set
want-to-use-syntax-in-pattern-matching (i ⟵[ n , pf , m ]⟶ j) = ℕ
This works fine, but when I case-split via C-c C-c, it uses goo instead of my syntax. Is there any way to make case splitting use my declared syntax ?
(
Incidentally, using
syntax goo n i m j pf = i ─[ n , pf , m ]⟶ j
fails, where ─ is produced by \---
)
Nowadays Agda resugars patterns on the left if they are in scope unqualified
so this would just work.
Related
For a newcomer working through the LEAN documentation, it is sometimes quite frustrating to see that some simple problems turn into real bottlenecks when more difficult ones have apparently been solved. Here is what was supposed to be a simple self-produced exercise that turned into a few hours of frustration (there's no other way to LEARN, of course):
theorem prByCont : ∀ P : Prop, ( P → false ) → ¬ P :=
λ (P : Prop) (prf : P → false), prf
#check prByCont
example ( a b : ℕ ) (p: a = 2) (q: b=3) : ¬ (a ≥ b) :=
begin
apply prByCont,
assume h : a ≥ b,
have order : 2 < 3 := dec_trivial,
contradiction
end
The problem seems to be that order has type 2<3 but what is needed is a<b, and although it looks to me that it should be clear that a=2 and b=3, LEAN doesn't think so. Please help me see what I'm missing here!
I have defined and proven the following lemma:
NM.In k m -> {NM.In k m0}+{NM.In k m1}.
I can also prove a symmetric lemma for:
{NM.In k m0}+{NM.In k m1} -> NM.In k m
However when I try to combine them into one as:
NM.In k m <-> {NM.In k m0}+{NM.In k m1}.
I got the following error:
The term "sumbool (#NM.In CarrierA k m0) (#NM.In CarrierA k m1)" has type
"Set" while it is expected to have type "Prop" (universe inconsistency: Cannot enforce
Set = Prop).
How this could be solved?
As Daniel pointed out, the problem is that the <-> connective only takes propositions as arguments, while sumbool lives in Set. This can be circumvented in a few ways: you can replace sumbool with or, or you can replace iff with a computationally relevant connective:
Variables A B C : Prop.
Check (({A} + {B} -> C) * (C -> {A} + {B}))%type.
I want to write the given coq code in agda.
Definition included (D1 D2:R -> Prop) : Prop := forall x:R, D1 x -> D2 x.
I have tried in this way ..
data included (D1 D2 : R -> Set) : Set where
forall x : R D1 x -> D2 x
I know the problem is in second line but how to fix it. Do we need to define constructor ?? And how will i do that??
please help.
data in Agda is the equivalent of Inductive in Coq: it introduces a new type defined inductively.
The equivalent of Definition in Agda is simply a defining equation for the thing you wish to define:
postulate R : Set
included : (_ _ : R → Set) → Set
included D1 D2 = ∀ x → D1 x → D2 x
I would like to build a kind of type hierarchy:
B is of type A ( B::A )
C and D are of type of B (C,D ::B)
E and F are of type of C (E,F ::C)
I asked here if this is possible to be directly implemented in Isabelle, but the answer as you see was No. Is it possible to encode this directly in Agda or Coq?
PS: Suppose A..F are all abstract and some functions are defined over each type)
Thanks
If I understood your question correctly, you want something that looks like the identity type. When we declare the type constructor _isOfType_, we mention two Sets (the parameter A and the index B) but the constructor indeed makes sure that the only way to construct an element of such a type is to enforce that they are indeed equal (and that a is of this type):
data _isOfType_ {ℓ} {A : Set ℓ} (a : A) : (B : Set ℓ) → Set where
indeed : a isOfType A
We can now have functions taking as arguments proofs that things are of the right type. Here I translated your requirements & assumed that I had a function f able to combine two Cs into one. Pattern-matching on the appropriate assumptions reveals that E and F are indeed on type C and can therefore be fed to f to discharge the goal:
example : ∀ (A : Set₃) (B : Set₂) (C D : Set₁) (E F : Set) →
B isOfType A
→ C isOfType B → D isOfType B
→ E isOfType C → F isOfType C
→ (f : C → C → C) → C
example A B .Set D E F _ _ _ indeed indeed f = f E F
Do you have a particular use case in mind for this sort of patterns or are you coming to Agda with ideas you have encountered in other programming languages? There may be a more idiomatic way to formulate your problem.
Suppose you want to define a family of binary operators (indexed by sets, say) where the types of the arguments depends on the value of the index, and the index is passed explicitly. In addition, suppose you would like a member of the family to be usable in infix notation:
x <[A] y
A here is the index; the brackets [-] are supposed to indicate that A should be read as a subscript. Giving a type signature for such an operation compatible with this syntax is difficult because the type of x depends on the value A, and so A : Set must occur to the left of x : A in the definition of _<[_]_.
I've experimented with the following trick (hack?) based on syntax declarations:
cmp : (A : Set) → A → A → Set
cmp = {!!}
syntax cmp A x y = x <[ A ] y
postulate C : Set
postulate c : C
x = c <[ C ] c
This seems to work, unless your binary operation uses implicit instances. If I try to add arguments of the form {{x}} to a syntax declaration, Agda complains. (Not unreasonably, perhaps.)
It seems one can adapt the idiom by introducing a version of cmp which takes the implicit instance explicitly, and then define a variant of the syntax which invokes that version:
postulate B : Set
-- Now expects an ambient B.
cmp : (A : Set) {{b : B}} → A → A → Set
cmp = {!!}
-- Version of cmp that makes implicit instance explicit.
cmp-explicit : (A : Set) (b : B) → A → A → Set
cmp-explicit A b = cmp A {{b}}
syntax cmp A x y = x <[ A ] y
syntax cmp-explicit A b x y = x <[ A at b ] y
postulate C : Set
postulate c : C
postulate b : B
x = c <[ C ] c -- pick up ambient B
y = c <[ C at b ] c -- pass B explicitly
(Since syntax doesn't appear to support {{x}} arguments, one cannot just inline cmp into cmp-explicit, without giving up the ability to pick up an ambient B entirely.)
Is this a hack? Is there another way to flip arguments x and y when the type of y depends on the value of x, and x is passed explicitly?
Naturally, defining
_<′[_]_ = λ x A y → cmp A x y
causes Agda to complain when typechecking x.
You can't really flip the arguments in a way that A : Set comes after x : A.
You already mentioned syntax, which I think is the best solution. This works because Agda will transform x <[ A ] y into cmp A x y and that's fine with the type checker.
Here's another (rather ugly and hacky) approach. Let's say we have:
_<[_]_ : {A : Set} → A → ? → A → Set
Here we can exploit unification a bit: by using something that mentions A in the ? hole, we can force the type checker to fill in the implicit A in front. But as far as I know, there's no simple type we can use in place of ?, so that we get the required x <[ A ] y. But to finish the thought, here's one thing that works:
data Is : Set → Set₁ where
is : (A : Set) → Is A
_<[_]_ : {A : Set} → A → Is A → A → Set
x <[ is A ] y = cmp A x y
Yes, this is fairly ugly and I would recommend against it.
But back to your question about syntax: I would not consider syntax to be a hack in any way. In fact, the standard library uses syntax in roughly the same way in one place (Data.Plus to be exact):
syntax Plus R x y = x [ R ]⁺ y
Even having cmp-explicit around is useful. I would even go as far as to suggest you make two extra versions:
cmp-syntax = cmp
cmp-explicit-syntax = λ A b → cmp A {{b}}
syntax cmp-syntax A x y = x <[ A ] y
syntax cmp-explicit-syntax A b x y = x <[ A at b ] y
If the user of your module does not want to use the syntactic shortcut (for example, he imports another module that defines _<[_]_), he can simply choose to not import it and still have cmp around.
Again, standard library does this with the syntactic shortcut for Σ. The shortcut allows you to write:
open import Data.Nat
open import Data.Product
open import Relation.Binary.PropositionalEquality
x : Σ[ n ∈ ℕ ] n + 2 ≡ 4
x = 2 , refl
And if you do not want it, then you simply:
open import Data.Product
hiding (Σ-syntax)