what is the meaning of infixr in Agda? - agda

Prp : Set₁
Prp = Set
data _∧_ (P Q : Prp) : Prp where
∧-intro : P -> Q -> P ∧ Q
infixr 2 _∧_
data _∨_ (P Q : Prp) : Prp where
∨-intro₁ : P -> P ∨ Q
∨-intro₂ : Q -> P ∨ Q
infixr 1 _∨_
there is part of code from a sample code. I am just wondering what the meaning of the infixr, and why it be used there.
Thanks

This is significant not to write parentheses in expression like
a ∧ b ∨ c
a * b + c
infixr/infixl - is a power to (r=right, l=left), when it is used in infix(between) position

Related

Derivatives of data structures in Agda

I am currently implementing derivatives of regular data structures, in Agda,
as presented in the One-Hole Context paper by Conor McBride [5].
In implementing it straight out of the OHC paper, which has also been done by Löh & Magalhães [3,4], we are left with the ⟦_⟧ function highlighted in red,
as Agda can't tell if the μ and I cases will terminate together.
Löh & Magalhães made a comment of this in their repository.
Other papers have also included a similar implementation or definitions in their papers [7,8] but do not
have a repo (at least I haven't been able to find it) [1,2,6],
or they follow a different approach [9] in which μ is defined separately
from Reg, ⟦_⟧, and derive (or dissection in their case), with no environment, and the operations are performed on a stack.
Using the {-# TERMINATING #-} or {-# NON_TERMINATING #-} flags
is undesirable. Particularly, anything using ⟦_⟧ will not normalize,
and thus I can't use this function to prove anything.
The implementation below is a slight modification to the OHC implementation.
It removes weakening and substitution as part of the structural definition of Reg.
Which, at first, makes ⟦_⟧ happy! But I find a similar problem when implementing
derive -- Agda's termination checker is not happy with the μ case.
I haven't been successful at convincing Agda that derive terminates.
I was wondering if anyone had successfully implemented derive with the
signature derive : {n : ℕ} → (i : Fin n) → Reg n → Reg n
The code below only shows some of the important pieces.
I have included a gist with the rest of the definitions, which includes definitions
of substitution and weakening and the derive that fails to terminate.
-- Regular universe, multivariate.
-- n defines the number of variables
data Reg : ℕ → Set₁ where
0′ : {n : ℕ} → Reg n
1′ : {n : ℕ} → Reg n
I : {n : ℕ} → Fin n → Reg n
_⨁_ : {n : ℕ} → (l r : Reg n) → Reg n
_⨂_ : {n : ℕ} → (l r : Reg n) → Reg n
μ′ : {n : ℕ} → Reg (suc n) → Reg n
infixl 30 _⨁_
infixl 40 _⨂_
data Env : ℕ → Set₁ where
[] : Env 0
_,_ : {n : ℕ} → Reg n → Env n → Env (suc n)
mutual
⟦_⟧ : {n : ℕ} → Reg n → Env n → Set
⟦ 0′ ⟧ _ = ⊥
⟦ 1′ ⟧ _ = ⊤
⟦ I zero ⟧ (X , Xs) = ⟦ X ⟧ Xs
⟦ I (suc n) ⟧ (X , Xs) = ⟦ I n ⟧ Xs
⟦ L ⨁ R ⟧ Xs = ⟦ L ⟧ Xs ⊎ ⟦ R ⟧ Xs
⟦ L ⨂ R ⟧ Xs = ⟦ L ⟧ Xs × ⟦ R ⟧ Xs
⟦ μ′ F ⟧ Xs = μ F Xs
data μ {n : ℕ} (F : Reg (suc n)) (Xs : Env n) : Set where
⟨_⟩ : ⟦ F ⟧ (μ′ F , Xs) → μ F Xs
infixl 50 _[_]
infixl 50 ^_
_[_] : {n : ℕ} → Reg (suc n) → Reg n → Reg n
^_ : {n : ℕ} → Reg n → Reg (suc n)
derive : {n : ℕ} → (i : Fin n) → Reg n → Reg n
derive = {!!}
Complete code:
https://pastebin.com/awr9Bc0R
[1] Abbott, M., Altenkirch, T., Ghani, N., and McBride, C. (2003). Derivatives of con- tainers. In International Conference on Typed Lambda Calculi and Applications, pages 16–30. Springer.
[2] Abbott, M., Altenkirch, T., McBride, C., and Ghani, N. (2005). δ for data: Differ- entiating data structures. Fundamenta Informaticae, 65(1-2):1–28.
[3] Löh, A. & Magalhães JP (2011). Generic Programming with Indexed Functors. In Proceedings of the seventh ACM SIGPLAN Workshop on Generic Programming (WGP'11).
[4] Magalhães JP. & Löh, A. (2012) A Formal Comparison of Approaches to Datatype-Generic Programming. In Proceedings Fourth Workshop on Mathematically Structured Functional Programming (MSFP '12).
[5] McBride, C. (2001). The derivative of a regular type is its type of one-hole contexts. Unpublished manuscript, pages 74–88.
[6] McBride, C. (2008). Clowns to the left of me, jokers to the right (pearl): dissecting data structures. In ACM SIGPLAN Notices, volume 43, pages 287–295. ACM.
[7] Morris, P., Altenkirch, T., & McBride, C. (2004, December). Exploring the regular tree types. In International Workshop on Types for Proofs and Programs (pp. 252-267). Springer, Berlin, Heidelberg.
[8] Sefl, V. (2019). Performance analysis of zippers. arXiv preprint arXiv:1908.10926.
[9] Tome Cortinas, C. and Swierstra, W. (2018). From algebra to abstract machine: a verified generic construction. In Proceedings of the 3rd ACM SIGPLAN Interna- tional Workshop on Type-Driven Development, pages 78–90. ACM.
The definition of derive terminates, you just adapted the code from the repo incorrectly. If derive is only called on F in the μ′ F case, that's clearly structural. In the code sample you tried to recurse on ^ (F [ μ′ F ]) instead.
derive : {n : ℕ} → (i : Fin n) → Reg n → Reg n
derive i 0′ = 0′
derive i 1′ = 0′
derive i (I j) with i ≟ j
derive i (I j) | yes refl = 1′
... | no _ = 0′
derive i (L ⨁ R) = derive i L ⨁ derive i R
derive i (L ⨂ R) = (derive i L ⨂ R) ⨁ (L ⨂ derive i R)
derive i (μ′ F) = μ′ ( (^ (derive (suc i) F [ μ′ F ]))
⨁ (^ (derive zero F [ μ′ F ])) ⨂ I zero)
I also suggest to adjust Reg as follows, since n as index is unnecessary, and Set₁ as well.
data Reg (n : ℕ) : Set where
0′ : Reg n
1′ : Reg n
I : Fin n → Reg n
_⨁_ : (l r : Reg n) → Reg n
_⨂_ : (l r : Reg n) → Reg n
μ′ : Reg (suc n) → Reg n

How to normalize rewrite rules that always decrease the input's size?

Mind the following datatype:
data AB : Set where
A : AB -> AB
B : AB -> AB
C : AB
rwt : AB -> AB
rwt (B (A ab)) = rwt ab
rwt (A ab) = A (rwt ab)
rwt (B ab) = B (rwt ab)
rwt C = C
ab : AB
ab = rwt (rwt (B (B (A (A (A (A (B (B (A (B C)))))))))))
Here, rwt is meant to replace all occurrences of B (A x) by x. The way it is written, though, doesn't guarantee the result is in normal form, which can be seen by the fact we needed two applications of rwt to get to A (A (B (B x))), which can't be further rewritten.
Is there any way to write reduce : AB -> AB in Agda that will return the same result as if we called rewrite repeatedly until no B (A x) is left? And, can we also get a proof of that (perhaps reduce : (input : AB) -> Σ AB (λ output . is-reduction-of input && is-in-nf output)?
An attempt:
The program below will always return the normal form of ab:
reduce : AB -> ℕ -> AB
reduce (A ab) (suc n) = reduce ab n
reduce (A ab) zero = A (reduce ab zero)
reduce (B ab) n = reduce ab (suc n)
reduce C (suc n) = B (reduce C n)
reduce C zero = C
But how do we prove it actually returns a term without "redexes", and that it is equivalent to rwt (rwt (rwt ... ab))? I'm asking because I expect there to be popular techniques to deal with that situation.
You could define rewriting inductively, then say that a normal term is not rewritable to anything. Then, prove that reduce is sound and returns normal forms.
open import Data.Empty
open import Data.Nat
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
data AB : Set where
A : AB -> AB
B : AB -> AB
C : AB
-- 1-step rewrite
infix 3 _~>_
data _~>_ : AB → AB → Set where
BA : ∀ {x} → B (A x) ~> x
A : ∀ {x y} → x ~> y → A x ~> A y
B : ∀ {x y} → x ~> y → B x ~> B y
-- reflexive-transitive closure
infixr 5 _◅_
data Star {A : Set}(R : A → A → Set) : A → A → Set where
ε : ∀ {x} → Star R x x
_◅_ : ∀ {x y z} → R x y → Star R y z → Star R x z
-- n-step rewrite
infix 3 _~>*_
_~>*_ : AB → AB → Set
_~>*_ = Star _~>_
normal : AB → Set
normal ab = ∀ {ab'} → ¬ (ab ~> ab')
-- TODO
reduceSound : ∀ ab → ab ~>* reduce ab 0
reduceNormal : ∀ ab → normal (reduce ab 0)
You will need to generalize reduceSound and reduceNormal for cases other than 0. Otherwise, both are provable by direct induction, so I don't think it could be made easier by any particular technique.

What could go wrong by ignoring dot pattern in Agda?

I am a noob in agda and reading http://www.cse.chalmers.se/~ulfn/papers/afp08/tutorial.pdf. My shallow knowledge somehow finds dot pattern not quite necessary. For example,
data Image_∋_ {A B : Set}(f : A → B) : B → Set where
im : (x : A) → Image f ∋ f x
inv : {A B : Set}(f : A → B)(y : B) → Image f ∋ y → A
inv f .(f x) (im x) = x
I find inv can well be defined as
inv : {A B : Set}(f : A → B)(y : B) → Image f ∋ y → A
inv _ _ (im x) = x
because from the types, we've already known y is an image of f for some x, so it cannot possibly go wrong.
Another example is
data _==_ {A : Set}(x : A) : A → Set where
refl : x == x
data _≠_ : ℕ → ℕ → Set where
z≠s : {n : ℕ} → zero ≠ suc n
s≠z : {n : ℕ} → suc n ≠ zero
s≠s : {n m : ℕ} → n ≠ m → suc n ≠ suc m
data Equal? (n m : ℕ) : Set where
eq : n == m → Equal? n m
neq : n ≠ m → Equal? n m
equal? : (n m : ℕ) → Equal? n m
equal? zero zero = eq refl
equal? zero (suc _) = neq z≠s
equal? (suc _) zero = neq s≠z
equal? (suc n') (suc m') with equal? n' m'
... | eq refl = eq refl
... | neq n'≠m' = neq (s≠s n'≠m')
consider equal? function, the second last line is written in the paper as (suc n') (suc .n') | eq refl = eq refl. Again, eq refl in with construct has provided a proof, for these two values being the same, so why do I bother writing them out using dot pattern?
I am more familiar with coq, and I am not aware of similar thing in coq. Am I missing something here?
In Coq you write the pattern-matches explicitly whereas Agda's equation-based approaches forces the typechecker to reconstruct a case-tree which ought to correspond to what you wrote.
Dotted-patterns help the typechecker see that a given pattern was not the product of a match but rather forced by a match on one of the other arguments (e.g.: a match on a Vec Bool n will force the value of n, or a match on an equality proof will, as you've observed, force some variables to be the same).
They're not always necessary and, in fact, some have been slowly made optional as you can see in the CHANGELOG for version 2.5.3:
Dot patterns.
The dot in front of an inaccessible pattern can now be skipped if the pattern consists entirely of constructors or literals. For example:

why this code is not working in agda?

I am trying to prove commutative property over natural number on multiplication operation.
--proving comm over *
*comm : ∀ a b → (a * b) ≡ (b * a)
*comm zero b = sym (rightId* b)
*comm (suc a) b = {!!}
when i check goal I found that it is b + a * b ≡ b * suc a. So i proved this.
lemma*-swap : ∀ a b → a + a * b ≡ a * suc b
Now when i tried :
*comm : ∀ a b → (a * b) ≡ (b * a)
*comm zero b = sym (rightId* b)
*comm (suc a) b = lemma*-swap b a
This should work as it satisfied the goal but why this is not working?? Please suggest me where I am wrong.
b + a * b (the expression in the goal) and a + a * b (the expression in lemma*-swap) are distinct so applying lemma*-swap does not satisfy the goal.
You need to rewrite the induction hypothesis *comm a b to turn a * b into b * a in the goal so that the expression lemma*-swap b a can be used to discharge the goal.

L-product-0 Theorem

I would like to prove the following:
𝕃-product-0 : ∀{l : 𝕃 ℕ} → list-any (_=ℕ_ 0) l ≡ tt → 𝕃-product l ≡ 0
𝕃-product-0 = {!!}
'list-any' is defined as:
list-any : ∀{ℓ}{A : Set ℓ}(pred : A → 𝔹)(l : 𝕃 A) → 𝔹
list-any pred [] = ff
list-any pred (x :: xs) = pred x || list-any pred xs
And _=ℕ_ is defined as:
_=ℕ_ : ℕ → ℕ → 𝔹
0 =ℕ 0 = tt
suc x =ℕ suc y = x =ℕ y
_ =ℕ _ = ff
I'm trying to understand this part: list-any (_=ℕ_ 0) l ≡ tt
Is (_=ℕ_ 0) ≡ (pred : A → 𝔹) and l ≡ (l : 𝕃 A)?
If so, I would like help understanding the predicate. What does (=ℕ 0) mean? I'm assuming =ℕ is applied like:
Foreach element in l return (element =ℕ 0).
Is this correct? I tried to prove the theorem by using a list l1:
𝕃-product-0 : ∀{l : 𝕃 ℕ} → list-any (_=ℕ_ 0) l ≡ tt → 𝕃-product l ≡ 0
𝕃-product-0 l1 = {!!}
but got the following error:
I'm not sure if there should be a case for the constructor refl,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
list-any (_=ℕ_ 0) l ≟ tt
when checking that the expression ? has type 𝕃-product .l ≡ 0
I appreciate any help given!
Edit (response 1):
I split the the case on the hole and got:
𝕃-product-0 : ∀{l : 𝕃 ℕ} → list-any (_=ℕ_ 0) l ≡ tt → 𝕃-product l ≡ 0
𝕃-product-0 x = {!!}
Is this the case that I want? It filled in x when I split.
It can also see that:
Goal: 𝕃-product .l ≡ 0
Where:
x : list-any (_=ℕ_ 0) .l ≡ tt
.l : 𝕃 ℕ
What is the program wanting me to solve at this point? How can I show that
𝕃-product-0 x is logically equivalent to 𝕃-product .l ≡ 0?
I'm trying to understand this part: list-any (=ℕ 0) l ≡ tt
Is (=ℕ 0) ≡ (pred : A → 𝔹) and l ≡ (l : 𝕃 A)?
You're correct in that _=ℕ_ 0 is substituted for pred. _=ℕ_ 0 means the result of applying the function _=ℕ_ to 0. Since _=ℕ_ is a binary function, applying it to just one argument yields a function ℕ -> 𝔹, which is what list-any expects.
As to the other question, you're trying to pattern match there on l, but it's implicit: in your example l1 actually denotes the list-any (_=ℕ_ 0) l ≡ tt argument, because that's the first explicit argument. You have to introduce the implicit argument using brackets:
𝕃-product-0 : ∀{l : 𝕃 ℕ} → list-any (_=ℕ_ 0) l ≡ tt → 𝕃-product l ≡ 0
𝕃-product-0 {l1} = {!!}
Edit:
I assume you're in Emacs agda-mode. When you look at the the context, the implicit arguments are prefixed with a dot, like .l : 𝕃 ℕ. If you're on a new-ish Agda, if you want to split on .l, write { .l } in the hole, then hit C-c-c. Another solution is to introduce the argument in the function definition using brackets, like how I wrote above, then write { l1 } in the hole, then hit C-c-c.
Alternatively, you can make the list argument explicit and save yourself the brackets:
𝕃-product-0 : (l : 𝕃 ℕ) → list-any (_=ℕ_ 0) l ≡ tt → 𝕃-product l ≡ 0
𝕃-product-0 l = ?
Just remember that in a function definition, arguments without brackets are the explicit arguments, and you can insert implicit arguments before or between them corresponding to the order they appear in the type. You can also refer to implicit arguments by their name in the type. For example:
foo : Nat -> {l : list Nat} -> Nat -> Nat
foo n m = ? -- now "n" refers to the first Nat and "m" refers to the last argument
foo : Nat -> {l : list Nat} -> Nat -> Nat
foo n {l} m = ? -- now "l" refers to the list.
foo : Nat -> {l : list Nat} -> Nat -> Nat
foo n {l = list} m = ? -- refer to "l" by the name "list" here.

Resources