Simplify pretty-printing of naturals

前端 未结 2 1919
小鲜肉
小鲜肉 2021-01-22 05:13

Let\'s say I wrote a function for reversing a list. I want to test it out using the value command, just to assure myself that I probably got it right. But the outpu

2条回答
  •  盖世英雄少女心
    2021-01-22 06:01

    Short answer: My first thought is to use type int, since (unlike nat) its code generator setup uses a binary numeral representation by default.

    Importing "~~/src/HOL/Library/Code_Target_Nat", as naT suggests, is also a good idea if you don't want to use the Suc representation for type nat.

    Explanation: Numerals in Isabelle are encoded using constructors defined in Num.thy; e.g. 5 is an abbreviation for numeral (Bit1 (Bit0 One)). Here One, Bit0 and Bit1 are constructors of type num. numeral is overloaded, and works for any type with a 1 and an associative +. Here are the code equations for numeral:

    lemma numeral_code [code]:
      "numeral One = 1"
      "numeral (Bit0 n) = (let m = numeral n in m + m)"
      "numeral (Bit1 n) = (let m = numeral n in m + m + 1)"
    

    If we generate code for 5::'a::numeral, then 1 and + on type 'a are treated as uninterpreted constants, so they remain in the output: (1 + 1) + (1 + 1) + 1.

    Generating code for 5::nat works the same, except we do have code for 1 and + on type nat, in terms of Suc. Thus (1 + 1) + (1 + 1) + 1 reduces further to Suc (Suc (Suc (Suc (Suc 0)))).

    Type int works differently. The code generator setup in Int.thy uses three constructor functions for type int: Pos and Neg of type num => int, as well as 0. A code_abbrev declaration causes each occurrence of numeral at type num => int to be replaced by Pos during code generation. After the code is run, Pos is then turned back into numeral before Isabelle displays the result. Thus 5::int evaluates to just 5.

    Special code setup theories: src/HOL/Library contains a few different theories for customizing code generation for numerals.

    • "~~/src/HOL/Library/Code_Target_Nat" tells the code generator to use the target language's (e.g. SML or Haskell's) built-in numerals for type nat. For example, 5::nat is usually translated to SML as numeral (Bit1 (Bit0 One)); however, with this library loaded it gets translated as 5 in SML. Results of value are translated back into the Isabelle numeral representation afterward.

    • "~~/src/HOL/Library/Code_Target_Int" is the same, but for type int instead of nat.

    • "~~/src/HOL/Library/Code_Target_Numeral" simply loads both of the previous two libraries. It only affects types nat and int, not any other types in class numeral.

    • "~~/src/HOL/Library/Code_Binary_Nat" configures nat in the same style as the default code setup for int: with constructors 0 and nat_of_num::num => nat and a code_abbrev declaration. With this library, value "5::nat" also returns 5.

提交回复
热议问题