为什么添加定义会更改语言环境导入的类型正确性?

Why would adding a definition change type-correctness of a locale import?

考虑这个例子——注意 F1F2 是相同的。

theory Scratch  
  imports Main
begin

locale F0 =   
  fixes meaning :: ‹'model ⇒ 'a set›  ("⟦_⟧")

locale F1 = F0 +
  fixes γ :: ‹'a set ⇒ 'model›
  assumes sound: ‹L ⊆ ⟦γ L⟧›
  (* Typechecks. *)

definition (in F0) "models m L ≡ L ⊆ ⟦m⟧"  

locale F2 = F0 +
  fixes γ :: ‹'a set ⇒ 'model›
  assumes sound: ‹L ⊆ ⟦γ L⟧›
  (* Does not typecheck, see below. *)

end

语言环境 F2——与类型良好的 F1 相同,只是我们向 F0 添加了一个定义——类型检查失败并显示错误消息:

Type unification failed

Type error in application: incompatible operand type

Operator:  meaning :: 'a ⇒ 'b set
Operand:   γ L :: 'model

显然,当类型检查F2时,类型检查器是否突然决定自由类型变量'a'model不可能是同一件事?

Isabelle 工具倾向于在任何地方“规范化”类型变量的名称,包括语言环境。当他们这样做时,所有类型变量都被从左到右替换为 'a'b'c 等。显然,definition 命令以某种方式触发了它。于是,F0中的'a'model一下子变成了'b'a

如果你想覆盖它,你可以明确地重新指定类型变量:

locale F2 = F0 meaning
  for meaning :: "'model ⇒ 'a set" +
  fixes γ :: ‹'a set ⇒ 'model›
  assumes sound: ‹L ⊆ meaning (γ L)›

locale F2 = F0 +
  constrains meaning :: "'model ⇒ 'a set"
  fixes γ :: ‹'a set ⇒ 'model›
  assumes sound: ‹L ⊆ meaning (γ L)›