繁体   English   中英

定义一个返回一个满足条件的元素的函数

[英]Defining a function that returns one element satisfying the condition

我想声明一个函数,该函数可将b等于true的元素(b,n)生成。

Require Export List.
Import Coq.Lists.List.ListNotations.

Definition lstest := list (bool * nat).


Fixpoint existbool (l : lstest) : option (bool * nat) :=
match l with
| [] => None
| (b, n) :: l' => if b then Some (b, n) else existbool l'
end.

该函数始终获得满足b = true的第一个元素。 我想表示存在一个满足b = true的元素并返回该元素。 如何定义这样的功能?

在下面的函数中, existbool_ex的类型告诉您我们输出包含在列表中的一对,其第一个元素为true(假设我们输出Some )。

(* These are all from the standard library *)
Locate "{ _ : _ | _ }".
Print sig.
Print In.
Print fst.

(* Defining Property here to shorten code for exist *)
Definition P l (x : bool * nat) := fst x = true /\ In x l.

Fixpoint existbool_ex (l : list (bool * nat)) :
  option {x : bool * nat | fst x = true /\ In x l} :=
  match l return option {x : bool * nat | P l x} with
  | [] => None
  | x' :: l' =>
    match x' with
    | (true,n) as ans =>
      Some (exist (P (ans :: l')) ans (conj eq_refl (or_introl eq_refl)))
    | (false,n) =>
      match existbool_ex l' with
      | None => None
      | Some (exist _ x a) =>
        match a with
        | conj Heq Hin =>
          Some (exist (P ((false, n) :: l')) x (conj Heq (or_intror Hin)))
        end
      end
    end
  end.

(* Note the as pattern got desugared into a let binding. *)
Print existbool_ex.

(* However we have a somewhat sane extraction, (tail recursive) *)
Require Extraction.
Extraction existbool_ex.

您可以编写函数get_number ,该函数需要证明列表在某处具有true值。

Definition has_true (l : lstest):= exists n, In (true, n) l.

get_number用的帮助下定义的refine ,它可以让我们离开“洞”(写_在证明词后来填写)。 这里有两个孔; 一种用于列表为[]时的荒谬情况,另一种用于为递归调用构造证明项。

Fixpoint get_number (l:lstest) (H: has_true l) : nat.
  refine (
      match l as l' return l' = _ -> nat with
      | (true, n)::_ => fun L => n
      | (false, _)::l' => fun L => get_number l' _
      | [] => fun L => _
      end eq_refl).

  now exfalso; subst l; inversion H.

  now subst l; inversion H; inversion H0;
    [congruence |  eexists; eauto].

Defined.

该函数使用convoy模式,以便match语句不会忘记不同分支中l的形状。

如果愿意,可以证明重写引理以使其更易于使用。

Lemma get_number_false l m H: exists H', get_number ((false, m)::l) H = get_number l H'.
Proof. eexists; reflexivity. Qed.

Lemma get_number_true l m H: get_number ((true, m)::l) H = m.
Proof. reflexivity. Qed.

Lemma get_number_nil H m: get_number [] H <> m.
Proof.  now inversion H. Qed.

Lemma get_number_proof_irrel l H1 H2: get_number l H1 = get_number l H2.
Proof. induction l as [ | [[|] ?] l']; eauto; now inversion H1. Qed.

暂无
暂无

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

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