如何告诉simp实例化原理图变量?

时间:2018-06-02 16:49:04

标签: isabelle

在下面的例子中,我想用simp来证明一些术语 简单地输入lambda calculus typecheck。 我将每个类型检查规则添加为simp的重写规则,因此simp执行 条件重写并沿途创建逻辑示意图变量。 然而,在重写一些重写的​​边条件时,simp得到了 坚持重写涉及原理图变量的术语,因为它没有 实例化它们:

theory Stlc imports Main
begin

type_synonym var = string

datatype exp =
    Var var
  | Const nat
  | Plus exp exp
  | Abs var exp
  | App exp exp

datatype type =
   Nat |
   Fun type type

type_synonym ('k, 'v) fmap = "'k ⇒ 'v option"

definition lookup :: "('k, 'v) fmap ⇒ 'k ⇒ 'v option" where
  "lookup m x = m x"

definition add :: "('k, 'v) fmap ⇒ 'k ⇒ 'v ⇒ ('k, 'v) fmap" where
  "add m x a = (λy. if y = x then Some a else m y)"

definition empty :: "('k, 'v) fmap" where
  "empty = (λy. None)"

notation
  lookup (infix "$?" 60) and
  add ("_ $+ '( _ ', _ ')") and
  empty ("$0")

inductive hasty :: "(var, type) fmap ⇒ exp ⇒ type ⇒ bool" where
  HtVar:
    "G $? x = Some t
    ⟹ hasty G (Var x) t" |
  HtConst:
    "hasty G (Const n) Nat" |
  HtPlus:
    "⟦ hasty G e1 Nat;
       hasty G e2 Nat ⟧
    ⟹ hasty G (Plus e1 e2) Nat" |
  HtAbs:
    "hasty (G $+ (x, t1)) e1 t2
    ⟹ hasty G (Abs x e1) (Fun t1 t2)" |
  HtApp:
    "⟦ hasty G e1 (Fun t1 t2);
       hasty G e2 t1 ⟧
    ⟹ hasty G (App e1 e2) t2"

named_theorems my_simps "simplification rules for typechecking"

declare HtVar [my_simps]
declare HtConst [my_simps]
declare HtPlus [my_simps]
declare HtAbs [my_simps]
declare HtApp [my_simps]

declare lookup_def [my_simps]
declare add_def [my_simps]

lemma "hasty $0 (Plus (Const 1) (Const 1)) Nat"
  using [[simp_trace_new mode=full]]
  apply(simp add: my_simps)
  done

lemma "hasty $0 (Abs ''n'' (Abs ''m'' (Plus (Var ''n'') (Var ''m''))))
             (Fun Nat (Fun Nat Nat))"
  apply (simp add: my_simps)
  done

lemma "⟦P ∧ Q ⟧ ⟹ Q"
  apply (rule conjE)
  apply(simp) (* note: this simp step does instantiate schematic variables *)
  apply assumption
  done

(* but here, it seems that simp does not instantiate schematic variables: *)
lemma eleven: "hasty $0 (App (App 
    (Abs ''n'' (Abs ''m'' (Plus (Var ''n'') (Var ''m''))))
    (Const 7)) (Const 4)) Nat"
  using [[simp_trace_new mode=full]]
  apply (simp add: my_simps) (* seems to fail on unifying "?t1.3 = type.Nat" *)

简化程序跟踪的相关部分(我猜)如下:

    Apply rewrite rule? 
      Instance of Option.option.inject: Some ?t1.3 = Some type.Nat ≡ ?t1.3 = type.Nat
      Trying to rewrite: Some ?t1.3 = Some type.Nat 
        Successfully rewrote 
          Some ?t1.3 = Some type.Nat ≡ ?t1.3 = type.Nat 
Step failed 
  In an instance of Stlc.hasty.HtVar:
    (λy. if y = ''m'' then Some ?t1.1 else if y = ''n'' then Some ?t1.3 else $0 y) $? ''n'' = Some type.Nat ⟹
    hasty (λy. if y = ''m'' then Some ?t1.1 else if y = ''n'' then Some ?t1.3 else $0 y) (Var ''n'') type.Nat ≡ True
  Was trying to rewrite:
    hasty (λy. if y = ''m'' then Some ?t1.1 else if y = ''n'' then Some ?t1.3 else $0 y) (Var ''n'') type.Nat 

在失败的步骤之前,重写将在?t1.3 = type.Nat处停止。 但是,我希望将?t1.3 = type.Nat重写为True,并且 ?t1.3在此过程中type.Nat被实例化。 我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

Isabelle的简化器本身从不实例化目标中的任何原理图变量。这只能通过所谓的求解器来完成。例如,解算器HOL unsafe会尝试使用策略rule reflassumption。这就是⟦P ∧ Q ⟧ ⟹ Q的示例与simp一起使用的原因。

为了解决像HtVar这样的条件重写规则的假设,子目标也扮演着一个角色。子目标商确定如何解决条件。默认情况下,在HOL中,这是asm_simp_tac,即等效于方法simp (no_asm_simp)。该子代理商无法在假设中处理原理图的实例化。您可以通过启用其他简化程序跟踪来查看此内容:

using [[simp_trace]] supply [[simp_trace_depth_limit=10]]
apply (simp add: my_simps)

给出以下跟踪消息:

[6]Proved wrong theorem (bad subgoaler?)
hasty (λy. if y = ''m'' then Some ?t1.1 else if y = ''n'' then Some type.Nat else $0 y) (Var ''n'') type.Nat ≡ True
Should have proved:
hasty (λy. if y = ''m'' then Some ?t1.1 else if y = ''n'' then Some ?t1.3 else $0 y) (Var ''n'') type.Nat

因此,如果您想使用简化器进行此类型检查,则需要使用不同的子目标。我没有足够的专家来帮助你。您可以在Isabelle / Isar参考手册的9.3.6节中找到更多文档。

相反,我建议你编写自己的类型推断方法(例如,使用Eisbach),它应用类型推理规则并根据需要调用简化器。这避免了子目标的问题。

答案 1 :(得分:0)

对于这种可以通过重复应用推理规则来解决的证明目标,人们应该使用经典推理器(auto)而不是重写器(simpl)。 / p>

如果我将所有输入规则声明为安全的介绍规则:

declare HtVar [intro!]
declare HtConst [intro!]
declare HtPlus [intro!]
declare HtAbs [intro!]
declare HtApp [intro!]

然后我的大部分引理都由auto证明,这留下了两个可以通过simp解决的查找目标:

lemma eleven: "hasty $0 (App (App 
    (Abs ''n'' (Abs ''m'' (Plus (Var ''n'') (Var ''m''))))
    (Const 7)) (Const 4)) Nat"
  apply(auto)
  apply(simp_all add: my_simps)
  done

另外,给定一个经典的推理器,如auto,可以很容易地指定在剩余的子目标上使用哪个重写器,如下所示,所以上面的证明可以压缩成一行:

apply(auto simp add: my_simps)

然而,给定simp之类的重写器,指定在剩余子目标上使用哪种方法似乎更为复杂。