Convert indexed Agda data type to record - agda

I have a record type which allowes invalid instances as they might be from an external source. E.g.
record Foo : Set where
fields
x : Nat
y : Nat
z : Nat
Now I have a validator which returns a proof that a given Foo conforms to certain propositions. The type of the proof could be for example:
data IsValidFoo : Foo → Set where
validFoo : (foo : Foo) → Even (Foo.x foo) → (Foo.y foo) < (Foo.z foo) → IsValidFoo foo
validateFoo : (foo : Foo) → Maybe (IsValidFoo foo)
…
I want to be able to access the individual proofs in IsValidFoo by name and thought of converting IsValidFoo to a record type. Is this even possible and how could it be achieved given that I want its type to stay IsValidFoo : Foo → Set?

Sure, this is possible by defining IsValidFoo as a record type parametrized over foo : Foo:
open import Agda.Builtin.Nat hiding (_<_)
postulate
_<_ : Nat → Nat → Set
Even : Nat → Set
Maybe : Set → Set
record Foo : Set where
field
x : Nat
y : Nat
z : Nat
record IsValidFoo (foo : Foo) : Set where
constructor validFoo
field
even-x : Even (Foo.x foo)
y<z : (Foo.y foo) < (Foo.z foo)
validateFoo : (foo : Foo) → Maybe (IsValidFoo foo)

Related

Agda: Constructing a recursive record value?

I'm wondering, is it possible to have records whose values depend on each other, without being recursively defined in terms of types?
Basically, I have a record type that looks like this:
record SomeRec (a : Set) : Set where  
method1 : a -> a -> Foo  
method2 : a -> a -> Bar 
... 
method n : a -> a -> Baz
where n is large enough that I want to actually bundle all of these up as records, instead of just having a bunch of mutually recursive functions. (Also, I'm using SomeRec as an instance argument).
Notably, SomeRec is not recursive: none of its fields types refer to SomeRec.
Right now, I have a Description D, where FD : Set -> Set is the functor described by D. What I'm trying to show is the following:
 
muRec : ( FRec : (a : Set) -> SomeRec a -> SomeRec (FD a) ) -> SomeRec (mu D)
That is, if I can take a (SomeRec a) to a (SomeRec (F a)), then I can tie the knot recursively and show the instance for the whole thing.
In principle this can be done: each recursive call to a field of SomeRec would happen with strictly smaller arguments. If I were to just have 10 mutually recursive methods, it would work. But if I try to build the record, I end up passing muRec to FRec without its arguments decreasing.
So, what I'm wondering is: is there a way to show that this is well-founded? Can induction or coinduction help, even though the record type is not inductive or coinductive?
My current approach is to make a size-indexed version of D, and build SomeRec for size n out of SomeRec for size < n. But this is dramatically increasing the complexity of what I'm doing, and I'm having to use Brouwer ordinals to get size bounds on what I'm doing. So I'm wondering if there's a better way.
Thanks!
The FRec : (a : Set) -> SomeRec a -> SomeRec (FD a) argument is asking for too much. It shouldn't be asking for a full SomeRec a, but rather only for the results of calling those methods on the subterms of some x : FD a.
If the methods are really simply typed you could instead define
record Results : Set where
field1 : Foo
field2 : Bar
...
fieldn : Baz
Then have muRec have a type like
muRec : (FRec : (a : Set) (x : FD a) (y : FD a)
(IH : (t1 t2 : a) -> In t1 x -> In t2 y -> Results)
-> Results)
-> mu D -> mu D -> Results
The type of IH might need to be adjusted depending on your recursion pattern.
And In : {a : Set} -> a -> FD a -> Set is some predicate you should be able to define by using D, which should relate subtrees to their parent.

Agda: Function Parsing error

I'm new to agda, and following a simple example in the book little MLer. Could anyone help me to figure out why the compiler gives me a parsing error?
Thank you
data Shish (a : Set) : Set where
Bottom : a → Shish a
Onion : Shish a → Shish a
Lamb : Shish a → Shish a
Tomato : Shish a → Shish a
data Rod : Set where
Dagger : Rod
Fork : Rod
Sword : Rod
data Plate : Set where
Gold-plate : Plate
Silver-plate : Plate
Brass-plate : Plate
what_bottom : Shish (a : Set) → Bool
what_bottom (Bottom x) → x
what_bottom (Onion x) → what_bottom x
what_bottom (Lamb x) → what_bottom x
what_bottom (Tomato x) → what_bottom x
/Volumes/Little/mko_io/cat/tmp/mler.agda:54,24-24
/Volumes/Little/mko_io/cat/tmp/mler.agda:54,24: Parse error
:<ERROR>
Set) → Bool
what_bottom (Bott...
The data type definitions are properly defined, but this is not the way one defines functions in Agda. A good starting tutorial is Dependent types at work
Functions are defined with the equal sign.
id : {A : Set} → A → A
id a = a
Moreover, the dependent type must be declared before like so either implicitly or explicitly.
what_bottom : {A : Set} → Shish A → ...
Lastly, that function cannot be defined with a return type Bool. It can have type a though.
As an additional syntactic point, in Agda, underscores are placeholders for mixfix arguments: what_bottom is a mixfix name with one parameter between what and bottom. So you'll end up with a function that you'd use as what (Onion $ Lamb $ Bottom) bottom which is probably not what you intended. Just call it whatBottom or what‿bottom if you're feeling extra.

from where it getting second argument in agda?

In the following data type,
data _≡_ {A : Set} (x : A) : A → Set where
refl : x ≡ x
I am trying to understand this like:
If A is of type Set and is implicit and x is the first argument and of type A, then this will construct a data of type A → Set.
Please explain it. I did not get from where it getting second x, in constructor refl.
The crucial distinction here is between parameters (A and x in this case) and indices (the A in A → Set).
The parameters are located on the left hand side of the colon in the data declaration. They are in scope in the body of the type and may not vary (hence their name). This is what allows you to write data declarations such as List where the type of the elements contained in the List is stated once and for all:
data List (A : Set) : Set where
nil : List A
cons : A → List A → List A
rather than having to mention it in every single constructor with a ∀ A →:
data List : Set → Set1 where
nil : ∀ A → List A
cons : ∀ A → A → List A → List A
The indices are located on the right hand side of the colon in the data declaration. They can be either fresh variables introduced by a constructor or constrained to be equal to other terms.
If you work with natural numbers you can, for instance, build a predicate stating that a number is not zero like so:
open import Data.Nat
data NotZero : (n : ℕ) → Set where
indeed1 : NotZero (suc zero)
indeed2+ : ∀ p → NotZero (suc (suc p))
Here the n mentioned in the type signature of the data declaration is an index. It is constrained differently by different constructors: indeed1 says that n is 1 whilst indeed2+ says that n has the shape suc (suc p).
Coming back to the declaration you quote in your question, we can reformulate it in a fully-explicit equivalent form:
data Eq (A : Set) (x : A) : (y : A) → Set where
refl : Eq A x x
Here we see that Eq has two parameters (A is a set and x is an element of A) and an index y which is the thing we are going to claim to be equal to x. refl states that the only way to build a proof that two things x and y are equal is if they are exactly the same; it constraints y to be exactly x.

How to obtain a list of values from a Data.AVL.Tree?

I'm easily able to obtain a list of Keys, as follows:
open import Relation.Binary
open import Relation.Binary.PropositionalEquality using (_≡_)
module AVL-Tree-Functions
{ k v ℓ } { Key : Set k }
( Value : Key → Set v )
{ _<_ : Rel Key ℓ }
( isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_ )
where
open import Data.AVL Value isStrictTotalOrder public
open import Data.List.Base
open import Function
open import Data.Product
keys : Tree → List Key
keys = Data.List.Base.map proj₁ ∘ toList
But I'm not clear on how to specify the type of function that returns a list of values. Here's my first attempt:
-- this fails to typecheck
values : Tree → List Value
values = Data.List.Base.map proj₂ ∘ toList
Relatedly, I'm also confused about the declaration of Value in Data.AVL. With ( Value : Key → Set v ), it looks like the type of each Value in the tree is dependent on the key? Or, something like that. I then figured that proj₂ would be returning something of type Set v, so I tried this:
-- this also fails to typecheck
values : Tree → List (Set v)
values = Data.List.Base.map proj₂ ∘ toList
But that doesn't work either (it fails with a different error). Please show how to get a list of values from a Data.AVL.Tree (or explain why it's impossible). Bonus: explain why my two attempts failed.
P.s. This is using version 2.4.2.3 of Agda and the agda-stdlib.
it looks like the type of each Value in the tree is dependent on the
key?
Yes. And that's why your code doesn't typecheck — Lists are homogeneous, but different Values have different indices (i.e. depend on different Keys) and hence different types.
You can use heterogeneous lists as in gallais' answer, but indexed lists might be enough in your case:
open import Level
data IList {ι α} {I : Set ι} (A : I -> Set α) : Set (ι ⊔ α) where
[]ᵢ : IList A
_∷ᵢ_ : ∀ {i} -> A i -> IList A -> IList A
projs₂ : ∀ {α β} {A : Set α} {B : A -> Set β} -> List (Σ A B) -> IList B
projs₂ [] = []ᵢ
projs₂ ((x , y) ∷ ps) = y ∷ᵢ projs₂ ps
Or you can combine the techniques:
data IHList {ι α} {I : Set ι} (A : I -> Set α) : List I -> Set (ι ⊔ α) where
[]ᵢ : IHList A []
_∷ᵢ_ : ∀ {i is} -> A i -> IHList A is -> IHList A (i ∷ is)
projs₂ : ∀ {α β} {A : Set α} {B : A -> Set β}
-> (xs : List (Σ A B)) -> IHList B (Data.List.Base.map proj₁ xs)
projs₂ [] = []ᵢ
projs₂ ((x , y) ∷ ps) = y ∷ᵢ projs₂ ps
What Value : Key → Set v means is that the type of the value may depend on the key it is associated to. This means that an AVL tree may contain Booleans, Nats, and so on as long as the key they are stored in reflects that fact. A bit like the fact that records can store values of different types (the types are determined by the field's name).
Now, they are different ways to do this: you can extract the content of the whole tree to a list of key / value pairs (because a list's elements are all the same, you need to build a pair here so that everything has the same type Σ Key Value). This is what toList does.
An alternative is to use what is usually called an HList (the H stands for heterogeneous) which stores in a list at the type level the type each one of its elements is supposed to have. I define it here by induction on the set of elements for size reasons but it is not at all crucial (if you were to define it as a datatype, it would live one level higher):
open import Level
open import Data.Unit
HList : {ℓ : Level} (XS : List (Set ℓ)) → Set ℓ
HList [] = Lift ⊤
HList (X ∷ XS) = X × HList XS
Now, you can give the type of the HList of values. Given t a Tree, it uses your keys to extract the list of keys and turns them into Sets by mapping Value over the list.
values : (t : Tree) → HList (List.map Value (keys t))
Extracting the values can then be done with the help of an auxiliary function working along the list produced by toList:
values t = go (toList t) where
go : (kvs : List (Σ Key Value)) → HList (List.map Value $ List.map proj₁ kvs)
go [] = lift tt
go (kv ∷ kvs) = proj₂ kv , go kvs

How to write this in agda?

I wanted to implement this statement in agda ;
A dedekind cut is a pair (L, U) of mere predicates L : Q -> Set and R : Q -> Set which is
1) inhibited : exists (q : Q) . L(q) ^ exists (r : Q) . U(r)
I have tried in this way,
record cut : Set where
field
L : Q -> Set
R : Q -> Set
inhibited : exists (q : Q) . L(q) ^ exists (r : Q) . U(r)
but this is not working. I want to write this and i am struck please help. And also what is the difference between 1)data R : Set and record R : Set and 2) data R : Set and data R : Q -> Set
I don't know about defining the whole of the dedekind cut, though I did find your definition on page 369 of Homotopy Type Theory: Univalent Foundations of Mathematics.
Here is the syntax for defining what you asked about in your question in two forms, one using the standard library and one expanded out to show what it is doing.
open import Data.Product using (∃)
record Cut (Q : Set) : Set₁ where
field
L U : Q → Set -- The two predicates
L-inhabited : ∃ L
U-inhabited : ∃ U
If we manually expand the definition of ∃ (exists) we have:
record Cut′ (Q : Set) : Set₁ where
field
L U : Q → Set -- The two predicates
q r : Q -- Witnesses
Lq : L q -- Witness satisfies predicate
Ur : U r -- Witness satisfies predicate
Note that the record has type Set₁ due to the types of fields L and U.
Regarding your question about records and inductively defined data types, there are lots of differences. You might want to start with the wiki and ask more specific questions if you get stuck somewhere: Data, Records

Resources