版本2-3-0

--------------------------------------------------------------------------Agda 2 2.3.0版的发行说明------------------------------------------------------------------------自2.2.10以来的重要变化:语言========*新的更自由的语法用于相互递归定义。不再需要使用“mutual”关键字来定义相互递归的函数或数据类型。相反,这足以在使用前先声明。而不是相互的f:答f=a[f,g]克:乙[f]g=b[f,g]你现在可以写了f:答克:乙[f]f=a[f,g]g=b[f,g]。有了新款式,您可以更自由地选择哪些东西是经过类型检查的(以前的类型签名是始终在定义之前检查)。此外,您可以混合任意声明,例如模块和假设相互递归的定义。对于数据类型和记录,使用以下新语法将声明与定义分开:--声明。数据Vec(A:设置):自然设置--注意没有“where”。--定义。数据Vec A,其中[]:Vec A零_::_:{n:Nat}A类兽医Vec A(例如)--声明。记录Sigma(A:设置)(B:A设置):设置--定义。记录Sigma A B,其中构造函数__字段fst:A序号:B fst当单独声明/定义私有或抽象时您应该将“private”关键字附加到声明和定义的“abstract”关键字。例如,一名私人,抽象函数可以定义为私有的f:答摘要f=e最后,值得注意的是仍然支持递归定义(它基本上可以分解为新样式)。*模式匹配lambdas。可以使用语法定义匿名模式匹配函数\{p11..p1n->e1;…;pm1..pmn->em}(其中,和往常一样,\和->可以替换为λ和→). 内部这被转换为以下形式的函数定义:.extlam第11页。。p1n=e1....extlam pm1。。pmn=em这意味着匿名模式匹配函数是生成性的。例如,ref不会被接受为该类型的居民(λ{真真;假})≡(λ{真真;错误}),因为对于一些不同的新名称extlam1和extlam2。目前,“where”和“with”结构不允许出现在(的顶级子句)匿名模式匹配函数。示例:和:布尔布尔布尔且=λ{真xx;错误_假}xor:布尔布尔布尔xor=λ{真真; 假假; _     _     真的}fst:{A:集}{B:A集合}∑A BA类fst=λ{(a,b)一个}snd:{A:集}{B:A集合}(p:∑A B)B(fst p)snd=λ{(a,b)b}(b)*记录更新语法。假设我们有一个记录类型和相应的值:record MyRecord:设置位置领域a b c:旧:MyRecord旧=记录{a=1;b=2;c=3}然后我们可以更新以下方式:新建:MyRecordnew=记录旧{a=0;c=5}这里,新的归一化记录{a=0;b=2;c=5}。任何可以使用产生MyRecord类型值的表达式来代替旧的。不允许更新记录以更改类型:结果值必须与原始类型相同,包括记录参数。因此,如果类型可以推断出原始记录的。记录更新语法在类型检查之前展开。表达记录旧的{up-fields}根据记录类型R进行检查,将其展开为设r=记录{new-fields}中的旧字段,其中旧的要求为R型,新的定义为如下:对于R中的每个字段x,-如果x=e包含在upd-field中,则x=e包括在新字段,以及其他-如果x是显式字段,则x=R.x R包含在新油田,以及-如果x是隐式或实例字段,则从新油田。(实例参数如下所述。)处理的原因隐式字段和实例字段特别允许以下内容:记录R:设置位置领域{长度}:vec:车辆长度--更多字段xs:R格式xs=记录{vec=0|1|2|[]}ys=记录xs{vec=0|[]}如果没有特殊处理,最后一个表达式需要包含一个新的长度绑定(例如“length=_”)。*记录不包含数据类型模式但不包含点图案,不再被拒绝。*使用--without-K标志时,文字现在被视为建造师。*应用不足的功能现在可以减少。考虑以下定义:id:{A:Set(设置)}A类A类id x=x以前表达式id不会减少。这已更改因此它现在减少到λxx。通常这不会带来什么区别,但与“with”结合使用可能很重要。请参见例如,第365期。*望远镜未使用的AgdaLight传统语法(xy:A;zv:B)具有已删除。宇宙多态性---------------------*现在默认情况下启用了Universe多态性。使用--no-universe-polymorphy将其禁用。*人群级别不再定义为数据类型。基本级别的组合子可以通过以下方式引入:假设级别:设置zero:级别suc:级别水平最大:级别水平水平{-#构建级别#-}{-#BUILTIN LEVELZERO零#-}{-#构建级别suc#-}{-#BUILTIN LEVELMAX最大#-}*BUILTIN等式现在被要求是宇宙多态的。*trustMe现在是通用多态的。元变量与统一------------------------------*未解决的元变量现在在每个相互块后都被冻结。这意味着它们不能由后续代码实例化。对于实例,一个:Nat一个=_bla:一≡零bla=回流现在导致错误,而以前它会导致用“suc zero”实例化_。如果您想利用旧行为,将这两个定义放在一个相互的块中。在交互式编辑期间,所有元变量都会被解冻,以便用户可以交互地填充孔。请注意交互式给定的条件并不完美:Agda有时拒绝加载文件,即使在文件的交互式构造。这是因为某些检查(例如,positity)仅在加载文件时调用。*现在可以推断记录类型。如果有一个唯一的已知记录类型,其字段与字段,则表达式的类型将被推断为应用于未知参数的记录类型。如果给定字段中没有已知的记录类型检查器将给出错误,而不是生成大量未解决的问题元变量。请注意,“已知记录类型”是指任何导入的模块,而不仅仅是范围内的类型。*引用检查器区分刚性和强刚性事件[Reed,LFMTP 2009;Abel&Pientka,TLCA 2011]。完整性检查程序现在接受以下代码:h:(n:自然)n≡sucn国家h n()在内部,这会生成一个约束_n=suc _n,其中元变量n严格出现,即在构造函数路径上从根开始,在它自己的定义术语树中。这永远不会可解决。弱刚性递归事件可能有解决方案博士论文,第106页]:测试:(k:Nat)让X:(Nat国家)国家X=_在里面(f:国家国家)X f≡suc(f(X(λXk) ))测试k f=refl约束_X k f=suc(f(_X k(λXk))有解决方案_X k f=suc(f(suc k)),尽管递归出现_X。这里_X不是强刚性的,因为它发生在边界下变量f。此前,Agda拒绝了该代码;现在改为投诉未解决的元变量。*头部包含相同元变量的方程约束现在触发修剪【Pientka博士,第3.1.2节;Abel&Pientka,TLCA2011]. 例子:相同:让X:AA类A类A×AX=_在{xyz:A}中X X y y≠(X,y)×X X X y≡X X y y相同=回流,回流第二个方程意味着X不能依赖于它的第二个参数。修剪后,第一个方程是线性的,可以是已解决。*实例参数。添加了一种新类型的隐藏函数参数:instance论据。这个新功能基于Scala的影响隐式和Agda现有的隐式参数。纯隐式参数由单大括号标记:{}。实例参数由双大括号{{}}标记。例子:假设A:设置B:A设置答:答f:{{a:a}}B和a您可以使用符号⦃和⦄代替双大括号,但在许多情况下,这些符号必须被空白包围。(如果你正在使用Emacs和Agda输入法,然后你可以变戏法分别键入“\{{”和“\}}”将符号向上。)实例参数的行为与普通隐式参数相同,除了一个重要方面:解决未提供的参数明确地。例如,考虑以下代码:测试=f在这里,Agda会注意到f的实例参数没有提供显式地,并尝试推断它。范围中f的所有定义调用站点以及上下文中的所有变量都被考虑在内。如果这些名称中只有一个具有所需的类型(A),则实例参数将实例化为该名称。此功能可用作Haskell类型类的替代。如果我们定义记录等式(A:设置):设置其中字段相等:AA类布尔,然后我们可以定义以下投影:相等:{A:Set}{{eq:EqA}}A类A类布尔相等{{eq}}=相等现在考虑以下表达式:等于假假∨等于34如果Bool和在范围内,没有其他,则接受该表达式:eq工具:eq Booleq-Bool=记录{equal=}等式-ℕ:等式等式-ℕ = 记录{equal=}提供了一个简写符号,以避免定义手动投影功能:模块Eq-with-implicits=Eq{{…}}此符号创建Eq记录模块的变体,其中主Eq参数是一个实例参数,而不是显式参数。它相当于以下定义:模Eq与隐含{A:Set}{{Eq:EqA}}=Eqeq注意,使用简写符号可以避免将“-with-implicits”模块:打开等式{{…}}实例参数解析不是递归的。例如,考虑以下“参数化实例”:eq-List:{A:Set}等式A等式(列表A)eq列表{A}eq=记录{equal=eq列表-A}哪里eq-List-A:列表A列表A布尔eq-List-A[][]=真eq-List-A(A|as)(b|bs)=等于A b∧eq-Lest-A作为bseq-List-A _ _=假假设作用域中唯一的Eq实例是Eq-List和Eq-ℕ.则以下代码不进行类型检查:测试=相等(1|2|[])(3|4|[]])然而,我们可以通过构造合适的实例手动执行:试验′=相等(1|2|[])(3|4|[]])其中eq列表-ℕ = eq—列出eq-通过将“实例搜索”限制为非递归,我们避免了向Agda引入了一种新的仅编译时评估模型。有关实例参数的更多信息,请参阅Devriese&皮森斯【ICFP 2011】。中还提供了一些示例Agda发行版的examples/instance-arguments子目录。无关性-----------*依赖的无关函数类型。一些例子说明依赖无关的语法函数类型:.(x y:A)B、。{xyz:A}B∀x年B∀x。{y} {z}.vB声明f:。(x:A)B【x】f x=t[x]要求x在t[x]和B[x]中都是无关的。这是例如,如果B[x]=B′x,且B′:,则可能。A类设置。依赖无关性允许我们定义挤压类型:record Push(A:设置):设置位置构造函数挤压领域证明:Aelim-Squash:{A:设置}(P:挤压A设置)(ih:.(a:a)P(壁球a)(a)⁻ : 壁球A)太平洋elim-Squash P ih(南瓜a)=ih a请注意,这不会用(ih:(a:a)->P(南瓜a))。*只包含不相关字段的记录。以下内容现在有效:记录Is等价{A:Set}(_≈_:AA类Set):设置位置领域.ref:反射_≈_.sym:对称_≈_.trans:传递_≈_record Setoid:设置哪里中缀4≈_领域承运商:设置_≈_:载体承运人设置.is等效:isEquivalence_≈_open IsEquivalence是等效公共此前Agda对该应用程序提出投诉IsEquivalence就是Equivalent,因为isEquivality是不相关的,并且IsEquivalence模块需要相关参数。现在,什么时候记录模块是为只包含以下内容的记录生成的不相关的参数,记录参数变得不相关:模Is等价{A:Set}{_≈_:AA类集合}.(r:Is等价{A=A}_≈_)其中…*无关的东西不再在内部擦除。这意味着它们是作为普通术语打印的,而不是像以前那样“_”。*新的标志——实验无关性启用了不相关的宇宙只有一个构造函数时不相关数据的级别和匹配可用。这些特征是非常实验性的,可能会发生变化或消失。反思----------*反射API已扩展到镜像功能,如无关性、实例参数和宇宙多态性,以及允许(有限)访问定义。为了完整性,所有内置程序和原语如下所示:--姓名。假设名称:集合{-#BUILTIN QNAME名称#-}原始的--姓名平等。primQNameEquality:名称姓名布尔--参数是可见(显式)、隐藏(隐式)还是--实例参数?数据可见性:设置位置可见隐藏实例:可见性{-#构建隐藏可见性#-}{-#BUILTIN VISIBLE可见#-}{-#BUILTIN HIDDEN HIDDEN隐藏#-}{-#BUILTIN INSTANCE实例#-}--论据可以是相关的,也可以是无关的。数据相关性:设置位置相关无关:相关性{-#构建相关性相关性#-}{-#构建相关#-}{-#BUILTIN IRRELEVANT无关#-}--参数。数据参数A:设置位置参数:(v:可见性)(r:相关性)(x:A)精氨酸A{-#构建参数#-}{-#内置ARGARG参数#-}--条款。相互的data Term:设置位置--应用于参数的变量。变量:(x:ℕ) (参数:列表(参数项))期限--应用于参数的构造函数。con:(c:名称)(参数:列表(参数术语))期限--应用于参数的标识符。定义:(f:名称)(参数:列表(参数术语))期限--不同种类的λ-抽象。lam:(v:能见度)(t:术语)期限--Pi类型。圆周率:(t₁ : 精氨酸类型)(t₂ : 类型)期限--一种。sort:排序期限--还有别的吗。未知:术语数据类型:设置位置el:(s:排序)(t:术语)类型数据排序:设置位置--给定(可能是中性)电平的集合。集合:(t:术语)排序--给定混凝土标高的一组。点亮:(n:ℕ) → 排序--还有别的吗。未知:排序{-#BUILTIN AGDASORT排序#-}{-#BUILTIN AGDATYPE类型#-}{-#BUILTIN AGDATERM术语#-}{-#BUILTIN AGDATERMVAR变量#-}{-#BUILTIN AGDATERMCON con#-}{-#BUILTIN AGDATERMDEF定义#-}{-#构建AGDATERMLAM lam#-}{-#构建AGDATERMPI pi#-}{-#BUILTIN AGDATERMSORT排序#-}{-#BUILTIN AGDATERMUNSUPPORTED未知#-}{-#内置AGDATYPEEL el#-}{-#BUILTIN AGDASORSET集合#-}{-#BUILTIN AGDASORTLIT点亮#-}{-#BUILTIN AGDASORTUNSUPPORTED未知#-}假设--函数定义。功能:设置--数据类型定义。数据类型:集合--记录类型定义。记录:设置{-#BUILTIN AGDAFUNDEF函数#-}{-#BUILTIN AGDADATADEF数据类型#-}{-#BUILTIN AGDARECORDDEF记录#-}--定义。数据定义:设置位置函数:函数定义data-type:数据类型定义record′:记录定义constructor′:定义公理:定义primitive′:定义{-#BUILTIN AGDADEFINITION定义#-}{-#BUILTIN AGDADEFINITIONFUNDEF函数#-}{-#BUILTIN AGDADEFINITIONDATADEF数据类型#-}{-#BUILTIN AGDADEFINITIONRECORDDEF记录'#-}{-#BUILTIN AGDADEFINITIONDATACONSTRUCTOR构造函数'#-}{-#BUILTIN AGDADEFINITIONPOSTULATE公理#-}{-#BUILTIN AGDADEFINITIONPRIMITIVE原语'#-}原始的--具有给定名称的对象的类型。primQNameType:名称类型--具有给定名称的事物的定义。primQName定义:名称定义--给定数据类型的构造函数。primDataConstructors:数据类型列表名称例如,表达式primQNameType(引号零)定义上等于el(发光0)(定义(引用ℕ) [])(如果零是数据类型的构造函数ℕ).*新关键字:unquote。构造“unquote t”转换了阿格达术语的表示按以下方式转换为实际的Agda代码:1.参数t必须具有Term类型(请参阅上面的反射API)。2.该论点已被规范化。3.整个结构替换为正常形式,即处理为由用户编写的语法,并在通常的方式。示例:测试:unquote(def(引号ℕ) []) ≡ 测试=回流id:(A:设置)A类A类id=unquote(lam可见(lam可视(var 0[]))id-ok:id≡(λA(x:A)x)id-ok=回流*新关键字:quoteTerm。构造“quoteTerm t”类似于“quote n”,但报价仅限于名称n,quoteTerm接受条款t施工方式如下:1.推断t的类型。术语t必须是类型正确的。2.术语t被归一化。3.该结构被术语表示替换(参见正常形式的反射API)。任何未解决的元变量在术语中由“未知”术语构造器表示。示例:测试₁ : 引用项(λ{A:Set}(x:A)x) ≡lam隐藏(lam可见(var 0[]))测试₁ = 回流--局部变量表示为de Bruijn指数。测试₂ : (λ{A:集合}(x:A)引用项x)≡(λx变量0[])测试₂ = 回流--术语在被引用之前被规范化。测试₃ : quoteTerm(0+0)≡con(引号零)[]测试₃ = 回流编译器后端=================马隆佐-------*MAlonzo后端的FFI现在处理更好的方式。Agda类型和种类到Haskell的转换现在支持宇宙多态性假设。核心变化是函数类型的翻译已从T[[Pi(x:A)B]]=如果A是哈斯克尔类型的对于所有x()->T[[B]]否则,如果x在fv B中,则未定义其他的T[[A]->T[[B]]进入之内T[[Pi(x:A)B]]=如果x在fv B中,则对于所有x。T[[A]]->T[[B]]--注:T[[A]]不是单位。其他的T[[A]->T[[B]],常数(公设、构造器和文字)已从更改T[[k As]]=如果是COMPILED_TYPE k T,则T T[[As]]其他的未定义进入之内T[[k As]]=如果是COMPILED_TYPE k T,则T T[[As]]否则,如果编译k E,则()其他的未定义。例如,假设Haskell定义类型AgdaIO a b=IO b,我们可以通过以下方式设置universe-polymorphic IO:假设IO:∀{ℓ} → 设置ℓ → 设置return:{a}{a:设置a}A类IO A接口_>>=_:{ab}{a:集合a}{b:集合b}IO A接口(A)IO B)IO B(输入输出B){-#COMPILED_TYPE IO AgdaIO#-}{-#COMPILED返回(\__->return)#-}{-#编译_>>=_(\____->(>>=))#-}这是可以接受的,因为(假设universe级别类型为转换为Haskell单元类型“()”)(\__->返回):对于所有a.()->对于所有b.()->b->AgdaIO a b=T[[∀{a}{a:设置a}A类IO A]](\_ _ _ _ -> (>>=)):对于所有a.()->对于所有b.()->对于所有c.()->对于所有d.()->AgdaIO a c->(c->AgdaIO b d)->AgdaIOb d=T[[∀{ab}{a:集合a}{b:集合b}IO A接口(A)IO B)IO B]]。史诗----*新的Epic后端杂注:STATIC。在Epic后端,用STATIC杂注标记的函数将是编译前进行规范化。示例用法:{-#静态功率#-}功率:ℕ → ℕ → ℕ功率0 x=1功率1 x=x功率(suc n)x=功率n x*x出现“power 4 x”将替换为“((x*x)*x)**”。*在Epic后端实现了一些新的优化:-删除未使用的参数。执行工作者/包装器转换,以便未使用参数可以通过Epic的内联程序删除。例如,地图函数的转换方式如下:map_wrap:(A B:设置)(A)B)列表A列表Bmap_wrap A B f xs=map_work f xsmap_work f[]=[]map_work f(xбxs)=f xбmap_workf xs如果map_wrap是内联的(它将出现在任何饱和调用中),然后A和B在生成的代码中消失。使用抽象解释找到未使用的参数。尸体检查模块中的所有函数,以确定哪些变量使用。假设的行为是基于它们的类型。考虑返回,例如:假设返回:{A:Set}A类IO A接口可以删除return的第一个参数,因为它的类型为设置,因此不会影响程序在运行时的结果。-喷射检测。在运行时,许多函数可能是身份函数。强制后尤其如此。注入检测用更多功能取代了其中一些功能高效版本。例子:注入:{n:ℕ} → 财务n翅片(1+n)注入{suc n}zero=零inject{sucn}(suci)=suc(inject{n}i)强制删除Fin构造函数的参数,因此此函数是一个效率低下的身份函数,可以由以下一项:注入{}x=x为了真正找到这个函数,我们做了归纳假设该注入是其第二个参数和外观中的标识函数在函数的分支处,以决定这是否成立。注入检测也可以跨越数据类型障碍。例子:忘记:{A:Set}{n:ℕ} → 兽医列表A忘记[]=[]忘记(x|xs)=x|忘记xs假设构造函数标记(在编译的Epic代码中)车辆。[]和列表。[]是相同的,Vec._О_的标签列表。_б_也是一样的,这也是一个恒等函数。我们因此,可以用以下定义替换该定义:忘记{_}xs=xs为了尽可能频繁地应用这一点,构造函数标记如下已运行selected/after/injection检测,以使尽可能多的功能注入。每个源文件选择一次构造函数标记,因此有利于在同一个函数中定义像forget这样的转换函数模块作为数据类型之一。例如,如果Vec.agda进口List.agda,则应将forget函数放入Vec.agda确保向量和列表得到相同的标记(除非有其他标记注入函数对标记施加不同的约束优先考虑)。-粉碎。此优化可查找其值在运行时可推断的类型:*只有一个构造函数的数据类型,其中所有字段都是可推断本身就是可推断的。*设置是可推断的(因为它没有运行时表示)。返回可推断数据类型的函数可以被破坏表示它被一个简单返回推断值。可推断类型的一个重要例子是通常的命题等式类型(_ lect _)。返回命题等式的任何函数可以直接返回自反性构造函数,而无需计算任何东西。这种优化使更多的参数未被使用。它还使史诗代码更小,从而加快编译速度。JavaScript脚本----------*ECMAScript编译器后端。正在实现一个新的编译器后端,目标是ECMAScript(也称为JavaScript),目标是允许Agda程序在浏览器或其他ECMAScript环境中运行。后端仍处于实验阶段:核心语言是实现了,但仍缺少许多功能。可以使用以下命令从命令行调用ECMAScript编译器标志--js:agda--js--compile-dir=<dir><FILE>.agda每个源<FILE>.agda都编译为ECMAScript目标<DIR>/jAgda<顶层模块名称>.js。编译器也可以是使用Emacs模式调用(变量agda2-backend控件使用哪个后端)。请注意,ECMAScript是一种严格的语言,而不是懒惰的语言。Agda程序是完整的,这不应该影响程序语义,但这可能会影响他们的空间或时间使用。ECMAScript不支持代数数据类型或模式匹配。这些功能被转换为访问者模式的使用。对于实例,标准库的List数据类型和null函数被翻译成以下代码:exports[“List”]={};exports[“List”][“[]”]=函数(x0){返回x0[“[]”]();};exports[“List”][“_ _”]=功能(x0){返回函数(x1){返回函数(x2){返回x2[“_О_”](x0,x1);};};};exports[“null”]=函数(x0){返回函数(x1){返回函数(x2){返回x2({“[]”:函数(){return jAgda_Data_Tool[“Bool”][“true”];},“●”:功能(x3,x4){return jAgda_Data_Tool[“Bool”][“false”];}});};};};Agda记录被转换为ECMAScript对象,保留字段名称。顶级Agda模块转换为ECMAScript模块,遵循common.js模块规范。顶级Agda模块“Foo.Bar”被转换为ECMAScript模块“jAgda.Foo.Bar”。ECMAScript编译器不编译为Haskell,因此杂注与Haskell FFI(IMPORT、COMPILED_DATA和COMPILED)相关的是ECMAScript后端未使用。相反,有一个COMPILED_JS可以应用于任何声明的杂注。对于假设,它给出了ECMAScript代码由编译器发出。对于数据类型,它提供了一个函数应用于该类型的值和访问者对象。对于实例,自然数与ECMAScript整数的绑定(忽略溢出错误)是:数据ℕ : 设置位置零:例如:ℕ→ℕ{-#COMPILED_JS函数(x,v){if(x<1){return v.zero()}#-}{-#COMPILED_JS零0#-}{-#COMPILED_JS suc函数(x){return x+1;}#-}_+_ : ℕ → ℕ → ℕ零+n=nsuc m+n=suc(m+n){-#COMPILED_JS_+_函数(x){返回函数(y){返回x+y;};} #-}为了优化FFI代码,COMPILED_JS中的ECMAScript使用一个识别纯ECMAScript的函数子集,由函数、函数组成应用程序、返回、if-statements、if-expressions、,无副作用二进制运算符(无优先级,左关联),无副作用前缀操作符、对象(其中所有成员名称)、字段访问以及字符串和整数文本。可以使用require(“<module-id>”)语法导入模块:任何可以放置不纯代码或支持片段之外的代码在模块中并导入。工具=====*新标志--safe,可用于对不受信任的代码进行类型检查。此标志禁用假设、primTrustMe和“不安全”选项杂注,其中一些已知会使Agda不一致。拒绝的杂注:--允许的非受控元--实验无关性--警备型控制器--注入型构造器--无平衡检查--无阳性检查--不终止检查--大小-类型--键入类型注意,目前不可能定义宇宙使用--safe时的level或coinduction原语(因为它们必须作为假设引入)。这可以通过以下方式解决在第一次通过时键入检查受信任的文件,而不使用--safe,然后在第二遍中使用--safe已经过类型检查的人不会因为安全而重新进行类型检查已使用。*依赖关系图。新标志--依赖关系图=FILE可用于生成DOT包含模块依赖关系图的文件。生成的文件(file)可以使用点之类的工具进行渲染。*--no-unreachable-check标志已被删除。*投影函数突出显示为函数而不是领域。字段名(在记录定义和记录值中)为仍高亮显示为字段。*支持跳转到信息中提到的位置已添加缓冲区。*“make-install”命令不再全局安装Agda(通过默认设置)。
页面上次修改时间:2011年11月23日上午09:21
技术支持私人维基