如何比较Coq中的两个ASCII字符串?

时间:2016-12-15 10:59:32

标签: functional-programming coq

我想在Coq。

中比较两个ASCII字符串s1和s2

标准库似乎不包含用于此目的的功能吗?

证明字符串相等的规范方法是什么?

2 个答案:

答案 0 :(得分:5)

如果两个字符串相等,您可以使用string_dec函数来决定(因此后缀为_dec)。顺便提一下,这个名称略微违反了通常的Coq命名风格 - 它应该被命名为string_eq_dec - _eq_dec代表可判定的平等。 string_dec具有以下类型:

string_dec
     : forall s1 s2 : string, {s1 = s2} + {s1 <> s2}

让我举一个具体的例子。 Coq允许您在string_dec中使用if - 表达式,如普通的布尔值:

Require Import String.
Open Scope string_scope.

Coq < Compute if string_dec "abc" "abc" then 1 else 0.
     = 1
     : nat

Coq < Compute if string_dec "ABC" "abc" then 1 else 0.
     = 0
     : nat

答案 1 :(得分:4)

如果你打算在Coq中实际运行字符串比较,我建议使用布尔版本:

From Coq Require Import Bool Ascii String.

Definition eq_ascii (a1 a2 : ascii) :=
  match a1, a2 with
  | Ascii b1 b2 b3 b4 b5 b6 b7 b8, Ascii c1 c2 c3 c4 c5 c6 c7 c8 =>
    (eqb b1 c1) && (eqb b2 c2) && (eqb b3 c3) && (eqb b4 c4) &&
    (eqb b5 c5) && (eqb b6 c6) && (eqb b7 c7) && (eqb b8 c8)
  end.

Fixpoint eq_string (s1 s2 : string) :=
  match s1, s2 with
  | EmptyString,  EmptyString  => true
  | String x1 s1, String x2 s2 => eq_ascii x1 x2 && eq_string s1 s2
  | _, _                       => false
  end.

在我的测试中,它们通常快3倍,但如果涉及hnf策略(在校样中发生),则可能是一个数量级。

Time Compute if string_dec
     "Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
      Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
     "
     "Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
      Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
     " then 1 else 0.
(* around 0.015 *)

Time Compute eq_string
     "Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
      Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
     "
     "Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
      Hola como te llamas amigo? Hola como te llamas amigo? Hola como te llamas amigo?
     ".
(* around 0.005 *)