Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Isabelle中划分列表算法正确性的证明_Isabelle_Proof Of Correctness - Fatal编程技术网

Isabelle中划分列表算法正确性的证明

Isabelle中划分列表算法正确性的证明,isabelle,proof-of-correctness,Isabelle,Proof Of Correctness,我试图证明在线性时间内将整数列表拆分为等和子列表的算法是正确的。你可以看到我选择的算法 我想得到一些关于以下方面的反馈: 我对拆分函数定义的方便性 在我的情况下使用的“归纳”假设 请记住,到目前为止,我只使用apply脚本,没有使用Isar证明 以下是算法的初步实现和正确性定义: definition "ex_balanced_sum xs = (∃ ys zs. sum_list ys = sum_list zs ∧ x

我试图证明在线性时间内将整数列表拆分为等和子列表的算法是正确的。你可以看到我选择的算法

我想得到一些关于以下方面的反馈:

  • 我对拆分函数定义的方便性

  • 在我的情况下使用的“归纳”假设

  • 请记住,到目前为止,我只使用apply脚本,没有使用Isar证明

    以下是算法的初步实现和正确性定义:

    definition
      "ex_balanced_sum xs = (∃ ys zs. sum_list ys = sum_list zs ∧ 
                                      xs = ys @ zs ∧ ys ≠ [] ∧ zs ≠ [])"
    
    
     fun check_list :: "int list ⇒ int ⇒ int ⇒ bool" where
        "check_list [] n acc = False" |
        "check_list (x#xs) n acc = (if n = acc then True else (check_list xs (n-x) (acc+x)))"
    
    fun linear_split :: "int list ⇒ bool" where
    "linear_split [] = False" |
    "linear_split [x] = False" |
    "linear_split (x # xs) = check_list xs (sum_list xs) x" 
    
    要证明的定理如下:

    lemma linear_correct: "linear_split xs ⟷ ex_balanced_sum xs"
    
    例如,如果我将第一个含义解释为:

    lemma linear_correct_1: "linear_split xs ⟹ ex_balanced_sum xs"
      apply(induction xs rule: linear_split.induct)
    
    然后我得到一个我认为不合适的子目标列表:

  • 线性分割[]⟹ ex_平衡总和[]
  • ⋀十,。线性_分割[x]⟹ ex_平衡总和[x]
  • ⋀x v va.线性分割(x#v#va)⟹ ex#u平衡和(x#v#va)
  • 特别是,这些子目标没有归纳假设!(我说得对吗?)。我试图通过编写
    apply(归纳法xs)
    来执行不同的归纳法,但目标如下:

  • 线性分割[]⟹ ex_平衡总和[]
  • ⋀一个X。(线性分割)⟹ ex_平衡_总和x)⟹ 线性分割(a#xs)⟹ 前平衡和(a#x)
  • 这里的假设也不是归纳假设,因为它假设了一个蕴涵

    那么,定义这个函数以得到一个好的归纳假设的最佳方法是什么

    编辑(单功能版本)


    背景

    我能够证明一个函数(
    splitl
    )的定理
    linear\u correct
    ,它与问题陈述中的函数
    check
    非常相似。不幸的是,我宁愿不尝试将证明转换为应用脚本

    下面的证据是我开始调查这个问题后想到的第一个证据。因此,可能存在更好的证明


    证明大纲

    证明是基于列表长度的归纳法。特别是,假设

    splitl xs(sum_list xs)0⟹ ex_balanced_sum xs

    适用于长度小于
    l
    的所有列表。如果
    l=1
    ,则结果很容易显示。假设
    l>=2
    。然后列表可以用
    x#v#xs
    的形式表示。在这种情况下,如果可以使用
    splitl
    拆分列表,则可以显示(
    splitl\u reduce

    “拆分((x+v)#xs)(总和列表((x+v)#xs))0”
    (1)

    “x=sum_列表(v#xs)”
    (2)

    因此,根据(1)和(2)的案例进行证明。对于(1),列表的长度是
    (x+v)#xs)
    l-1
    。因此,通过归纳假设
    ex_balanced_sum(x+v)#xs)
    。因此,根据
    ex#u balanced_sum
    的定义,也就是
    ex#u balanced_sum x#v#xs
    。对于(2),可以很容易地看出,列表可以表示为
    [x]@(v#xs)
    ,并且在这种情况下,给定(2),它满足定义为
    ex#u balanced_sum
    的条件

    另一个方向的证明是类似的,并且基于与上述(1)和(2)相关的引理的相反:如果
    “splitl((x+v)#xs)(sum_list((x+v)#xs))0”
    “x=sum_list(v#xs)”
    ,那么
    “splitl(x#v#xs)(sum#list(x#v#xs)


    理论
    输入复杂的主
    开始
    定义
    “ex_balanced_sum xs=
    (∃ ys zs.sum_list ys=sum_list zs∧ xs=ys@zs∧ ys≠ [] ∧ zs≠ [])"
    有趣的拆分::“int列表⇒ int⇒ int⇒ “哪里
    “splitl[]s1 s2=False”|
    “splitl[x]s1 s2=False”|
    “splitl(x#xs)s1s2=((s1-x=s2+x)∨ 拆分xs(s1-x)(s2+x))”
    引理splitl\u reduce:
    假设“splitl(x#v#xs)(sum#u list(x#v#xs))0”
    显示“splitl((x+v)#xs)(sum_list((x+v)#xs))0∨ x=总和(v#xs)”
    证明-
    来自ASSM的prem_案例:
    “((x=总和列表(v#xs))∨ 自动拆分(v#xs)(总和列表(v#xs))x)
    {
    假设“splitl(v#xs)(sum#u list(v#xs))x”
    然后有“splitl((x+v)#xs)(sum_list((x+v)#xs))0”
    证明(感应x任意:x v)
    无案例,然后逐个simp显示
    下一个
    案例(Cons a xs)然后逐个simp显示
    量化宽松
    } 
    通过prem_案例展示?自动完成论文
    量化宽松
    (*大锤*)
    引理splitl_展开:
    假设“splitl((x+v)#xs)(sum_list((x+v)#xs))0∨ x=总和(v#xs)”
    显示“splitl(x#v#xs)(总和列表(x#v#xs))0”
    by(smt assms list.inject splitl.elims(2)splitl.simps(3)sum_list.Cons)
    引理splitl_to_sum:“splitl xs(sum_list xs)0⟹ ex_平衡_和xs”
    证明(归纳xs规则:长度_归纳)
    案例(1 x)显示?案例
    证明-
    获取x v xst,其中x_xst:“xs=x#v#xst”
    由(介子“1.prems”分裂l.elims(2))
    有以下主要案例:
    “splitl((x+v)#xst)(sum_list((x+v)#xst))0∨ x=总和列表(v#xst)”
    by(规则拆分,插入x_xst“1.prems”,规则subst)
    {
    假设“splitl((x+v)#xst)(sum_list((x+v)#xst))0”
    与“1.IH”一起,xxst具有simp的“ex_balanced_sum((x+v)#xst)”
    然后获得yst zst,其中
    yst_zst:“(x+v)#xst=yst@zst" 
    和sum_yst_eq_sum_zst:“sum_list yst=sum_list zst”
    和yst_ne:“yst≠ []" 
    和zst_ne:“zst≠ []"
    自动展开ex_balanced_sum_def
    然后获取ystt,其中ystt:“yst=(x+v)#ystt”
    by(metis附加、等式、Cons、conv)
    有了sum#yst#eq#sum#zst,simp就有了“sum#list(x#v#ystt)=sum#list zst”
    此外,还可以通过自动使用x#xst yst#zst ystt使用“xs=(x#v#ystt)@zst”
    此外还有“(x#v#ystt)≠ []由simp提供
    此外,与zst_ne一起使用的还有“zst≠ []由simp提供
    最终有“ex_balanced_sum xs”展开ex_balanced_sum_
    
    fun check :: "int list ⇒ int ⇒ int ⇒ bool" where
    "check [] n acc = False" |
    "check [x] n acc = False" |
    "check (x # y # xs) n acc = (if n-x = acc+x then True else check (y # xs) (n-x) (acc+x))"
    
    definition "linear_split xs = check xs (sum_list xs) 0"
    
    theory so_ptcoaatplii
    imports  Complex_Main
    
    begin
    
    definition
      "ex_balanced_sum xs = 
      (∃ ys zs. sum_list ys = sum_list zs ∧ xs = ys @ zs ∧ ys ≠ [] ∧ zs ≠ [])"
    
    fun splitl :: "int list ⇒ int ⇒ int ⇒ bool" where
      "splitl [] s1 s2 = False" |
      "splitl [x] s1 s2 = False" |
      "splitl (x # xs) s1 s2 = ((s1 - x = s2 + x) ∨ splitl xs (s1 - x) (s2 + x))"
    
    lemma splitl_reduce:
      assumes "splitl (x#v#xs) (sum_list (x#v#xs)) 0" 
      shows "splitl ((x + v)#xs) (sum_list ((x + v)#xs)) 0 ∨ x = sum_list (v#xs)"
    proof -
      from assms have prem_cases: 
        "((x = sum_list (v#xs)) ∨ splitl (v#xs) (sum_list (v#xs)) x)" by auto
      {
        assume "splitl (v#xs) (sum_list (v#xs)) x"
        then have "splitl ((x + v)#xs) (sum_list ((x + v)#xs)) 0"
        proof(induction xs arbitrary: x v)
          case Nil then show ?case by simp
        next
          case (Cons a xs) then show ?case by simp
        qed
      } 
      with prem_cases show ?thesis by auto
    qed
    
    (*Sledgehammered*)
    lemma splitl_expand:
      assumes "splitl ((x + v)#xs) (sum_list ((x + v)#xs)) 0 ∨ x = sum_list (v#xs)"
      shows "splitl (x#v#xs) (sum_list (x#v#xs)) 0"
      by (smt assms list.inject splitl.elims(2) splitl.simps(3) sum_list.Cons)
    
    lemma splitl_to_sum: "splitl xs (sum_list xs) 0 ⟹ ex_balanced_sum xs"
    proof(induction xs rule: length_induct)
      case (1 xs) show ?case
      proof-
        obtain x v xst where x_xst: "xs = x#v#xst" 
          by (meson "1.prems" splitl.elims(2))
        have main_cases:
          "splitl ((x + v)#xst) (sum_list ((x + v)#xst)) 0 ∨ x = sum_list (v#xst)"
          by (rule splitl_reduce, insert x_xst "1.prems", rule subst)
        {
          assume "splitl ((x + v)#xst) (sum_list ((x + v)#xst)) 0"
          with "1.IH" x_xst have "ex_balanced_sum ((x + v)#xst)" by simp
          then obtain yst zst where 
            yst_zst: "(x + v)#xst = yst@zst" 
            and sum_yst_eq_sum_zst: "sum_list yst = sum_list zst"
            and yst_ne: "yst ≠ []" 
            and zst_ne: "zst ≠ []"
            unfolding ex_balanced_sum_def by auto
          then obtain ystt where ystt: "yst = (x + v)#ystt" 
            by (metis append_eq_Cons_conv)
          with sum_yst_eq_sum_zst have "sum_list (x#v#ystt) = sum_list zst" by simp
          moreover have "xs = (x#v#ystt)@zst" using x_xst yst_zst ystt by auto
          moreover have "(x#v#ystt) ≠ []" by simp
          moreover with zst_ne have "zst ≠ []" by simp
          ultimately have "ex_balanced_sum xs" unfolding ex_balanced_sum_def by blast
        }
        note prem = this
        {
          assume "x = sum_list (v#xst)"
          then have "sum_list [x] = sum_list (v#xst)" by auto
          moreover with x_xst have "xs = [x] @ (v#xst)" by auto
          ultimately have "ex_balanced_sum xs" using ex_balanced_sum_def by blast
        }
        with prem main_cases show ?thesis by blast
      qed
    qed
    
    
    lemma sum_to_splitl: "ex_balanced_sum xs ⟹ splitl xs (sum_list xs) 0"
    proof(induction xs rule: length_induct)
      case (1 xs) show ?case
      proof -
        from "1.prems" ex_balanced_sum_def obtain ys zs where 
          ys_zs: "xs = ys@zs"
          and sum_ys_eq_sum_zs: "sum_list ys = sum_list zs"
          and ys_ne: "ys ≠ []"
          and zs_ne: "zs ≠ []"
          by blast
        have prem_cases: "∃y v yst. ys = (y#v#yst) ∨ (∃y. ys = [y])"
          by (metis remdups_adj.cases ys_ne)
        {
          assume "∃y. ys = [y]"
          then have "splitl xs (sum_list xs) 0"
            using splitl.elims(3) sum_ys_eq_sum_zs ys_zs zs_ne by fastforce
        }
        note prem = this
        {
          assume "∃y v yst. ys = (y#v#yst)"
          then obtain y v yst where y_v_yst: "ys = (y#v#yst)" by auto 
          then have 
            "sum_list ((y + v)#yst) = sum_list zs ∧ ((y + v)#yst) ≠ [] ∧ zs ≠ []"
            using sum_ys_eq_sum_zs zs_ne by auto
          then have ebs_ypv: "ex_balanced_sum (((y + v)#yst)@zs)"
            using ex_balanced_sum_def by blast
          have l_ypv: "length (((y + v)#yst)@zs) < length xs" 
            by (simp add: y_v_yst ys_zs)
          from l_ypv ebs_ypv have 
            "splitl (((y + v)#yst)@zs) (sum_list (((y + v)#yst)@zs)) 0"
            by (rule "1.IH"[THEN spec, rule_format])    
          with splitl_expand have splitl_ys_exp: 
            "splitl ((y#v#yst)@zs) (sum_list ((y#v#yst)@zs)) 0"
            by (metis Cons_eq_appendI)
          from ys_zs have "splitl xs (sum_list xs) 0" 
            by (rule ssubst, insert y_v_yst splitl_ys_exp, simp)
        }
        with prem prem_cases show ?thesis by auto
      qed  
    qed
    
    lemma linear_correct: "ex_balanced_sum xs ⟷ splitl xs (sum_list xs) 0"
      using splitl_to_sum sum_to_splitl by auto
    
    end