简体   繁体   English

映射字符串作为Agda中的键?

[英]Map with Strings as Keys in Agda?

I'm having some trouble figuring out how to properly make a Map with String keys in Agda. 我在弄清楚如何正确地在Agda中使用String键制作Map时遇到了一些麻烦。 I've got the following: 我有以下几点:

import Data.AVL.IndexedMap

Var = String

data Type where -- ...

alwaysType : Var -> Set
alwaysType _ = Type

open Data.AVL.IndexedMap alwaysType (StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder) 

This gives the error: 这给出了错误:

String != Σ String _Key_90 of type Set
when checking that the expression
StrictTotalOrder.isStrictTotalOrder strictTotalOrder has type
Relation.Binary.IsStrictTotalOrder .Agda.Builtin.Equality._≡_
__<__91

What is the proper way to open the Map module? 打开“地图”模块的正确方法是什么?

Note that the standard library's Data.AVL has been updated to accept strict total orders not based on propositional equality. 请注意,标准库的Data.AVL已更新,可以接受不基于命题相等性的严格总订单。

These days it is as simple as: 这些天,它很简单:

open import Data.String.Properties
open import Data.AVL strictTotalOrder

The Data.AVL.IndexedMap module is for (finite) maps where there is a family of types for the keys and the values, and the value associated with a given key shares the index with the value. Data.AVL.IndexedMap模块用于(有限)映射,其中键和值有一系列类型,并且与给定键关联的值与该值共享索引。

This is not what you want here, since you want all your keys to be String s. 这不是您想要的,因为您希望所有键都是String So just use Data.AVL (ie the version with non-indexed keys): 因此,只需使用Data.AVL (即具有未索引键的版本):

open import Data.String using (String)
open import Function using (const)

Key = String

postulate
  Value : Set

open import Relation.Binary using (StrictTotalOrder)
open import Data.AVL (const Value) (StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder)

Unfortunately, this still doesn't typecheck: 不幸的是,这仍然没有类型检查:

.Relation.Binary.List.Pointwise.Rel
(StrictTotalOrder._≈_ .Data.Char.strictTotalOrder)
(Data.String.toList x) (Data.String.toList x₁)
!= x .Agda.Builtin.Equality.≡ x₁ of type Set
when checking that the expression
StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder
has type IsStrictTotalOrder .Agda.Builtin.Equality._≡_ __<__10

That's because Data.String.strictTotalOrder uses pointwise equality (over the list of values of the Char s that make up the String ), and Data.AVL requires propositional equality. 这是因为Data.String.strictTotalOrder使用逐点相等(在组成StringChar值列表中),并且Data.AVL需要命题相等。 So the exact same example would work with, eg, keys: 因此,完全相同的示例将与键一起工作:

open import Data.Nat using (ℕ)
open import Function using (const)

Key = ℕ

postulate
  Value : Set

import Data.Nat.Properties
open import Relation.Binary using (StrictTotalOrder)

open import Data.AVL (const Value) (StrictTotalOrder.isStrictTotalOrder Data.Nat.Properties.strictTotalOrder)

So the next step needs to be to transform StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder into something of type IsStrictTotalOrder (_≡_ {A = String}) _ . 因此,下一步需要将StrictTotalOrder.isStrictTotalOrder Data.String.strictTotalOrder转换为IsStrictTotalOrder (_≡_ {A = String}) _ I'll leave that to someone else for now, but I'm happy to look into it later, when I have the time, if you can't get it working and noone else picks it up either. 我现在将其留给其他人,但是如果有时间,如果您无法使它正常工作,并且也没有其他人来找,我很乐意稍后进行调查。

EDITED TO ADD : Here's a (possibly horribly over-complicated) way of turning that StrictTotalOrder for String s from the standard lib into something that uses propositional equality: 编辑添加 :这是一种(可能非常复杂的)将StrictTotalOrder for String s从标准库转换为使用命题相等的方法:

open import Function using (const; _∘_; _on_)
open import Relation.Binary

open import Data.String
  using (String; toList∘fromList; fromList∘toList)
  renaming (toList to stringToList; fromList to stringFromList)

open import Relation.Binary.List.Pointwise as Pointwise
open import Relation.Binary.PropositionalEquality as P hiding (trans)
open import Data.Char.Base renaming (toNat to charToNat)

STO : StrictTotalOrder _ _ _
STO = record
  { Carrier = String
  ; _≈_ = _≡_
  ; _<_ = _<_
  ; isStrictTotalOrder = record
    { isEquivalence = P.isEquivalence
    ; trans = λ {x} {y} {z} → trans {x} {y} {z}
    ; compare = compare
    }
  }
  where
    open StrictTotalOrder Data.String.strictTotalOrder 
      renaming (isEquivalence to string-isEquivalence; compare to string-compare)

    -- It feels like this should be defined somewhere in the
    -- standard library, but I can't find it...
    primCharToNat-inj : ∀ {x y} → primCharToNat x ≡ primCharToNat y → x ≡ y
    primCharToNat-inj _ = trustMe
      where
        open import Relation.Binary.PropositionalEquality.TrustMe

    open import Data.List
    lem : ∀ {xs ys} → Pointwise.Rel (_≡_ on primCharToNat) xs ys → xs ≡ ys
    lem [] = P.refl
    lem {x ∷ xs} {y ∷ ys} (x∼y ∷ p) with primCharToNat-inj {x} {y} x∼y
    lem {x ∷ xs} {_ ∷ ys} (x∼y ∷ p) | P.refl = cong _ (lem p)

    ≡-from-≈ : {s s′ : String} → s ≈ s′ → s ≡ s′
    ≡-from-≈ {s} {s′} p = begin
         s ≡⟨ sym (fromList∘toList _) ⟩
         stringFromList (stringToList s) ≡⟨ cong stringFromList (lem p) ⟩
         stringFromList (stringToList s′) ≡⟨ fromList∘toList _ ⟩
         s′ ∎
      where
        open P.≡-Reasoning

    ≈-from-≡ : {s s′ : String} → s ≡ s′ → s ≈ s′
    ≈-from-≡ {s} {_} refl = string-refl {s}
      where
        open IsEquivalence string-isEquivalence renaming (refl to string-refl) using ()

    compare : (x y : String) → Tri (x < y) (x ≡ y) _
    compare x y with string-compare x y
    compare x y | tri< a ¬b ¬c = tri< a (¬b ∘ ≈-from-≡) ¬c
    compare x y | tri≈ ¬a b ¬c = tri≈ ¬a (≡-from-≈ b) ¬c
    compare x y | tri> ¬a ¬b c = tri> ¬a (¬b ∘ ≈-from-≡) c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM