我如何证明c - ' a'在[0,26]之内?

时间:2018-01-15 08:13:32

标签: ats

假设我有这段代码:

#include "share/atspre_staload.hats"

val letters = arrayref_make_elt<bool>(i2sz(26), false)

implement main0() =
  begin
    println!("found('a'): ", letters[0]);
    println!("found('f'): ", letters[5]);
  end

产生输出:

found('a'): false
found('f'): false

我想按字符索引letters。实际上,给定任何字符,只有当它是有效索引时,我才想索引letters

所以这几乎可行:

#include "share/atspre_staload.hats"

val letters = arrayref_make_elt<bool>(i2sz(26), false)

typedef letter = [c:int | c >= 'a' && c <= 'z'] char(c)
typedef letteri = [i:int | i >= 0 && i < 26] int(i)

(* fn letter2index(c: letter): letteri = c - 'a' *)  (* #1 *)

fn letter2index(c: letter): letteri =
  case- c of
  | 'a' => 0
  | 'f' => 5

fn trychar(c: char): void =  (* #2 *)
  if c >= 'a' && c <= 'z' then
    println!("found('", c, "'): ", letters[letter2index(c)])

implement main0() =
  begin
    trychar('a');
    trychar('f');
    trychar('+');  (* #3 *)
  end

如果我在#2将char更改为letter并在#3处删除trychar('+'),则会进行编译。但当然,我宁愿在#1进行减法而不是大量的字母,我应该将trychar应用于任何类型的char,而不仅仅是letter {1}}。

1 个答案:

答案 0 :(得分:1)

您想要的代码可以写成如下:

#include
"share/atspre_staload.hats"

stadef
isletter(c:int): bool = ('a' <= c && c <= 'z')

val
letters = arrayref_make_elt<bool>(i2sz(26), false)

fn
letter2index
{ c:int
| isletter(c)}
(c: char(c)): int(c-'a') = char2int1(c) - char2int1('a')

fn
trychar
{c:int}
(c: char(c)): void =
if
(c >= 'a') * (c <= 'z')
then
println!("found('", c, "'): ", letters[letter2index(c)])

implement main0() =
begin
  trychar('a');
  trychar('f');
  trychar('+');
end

在原始代码中,量词(forall和exists)未正确使用。