(* Title: IPv6.thy
Authors: Cornelius Diekmann
*)
theory IPv6
imports
IP_Address
NumberWang_IPv6
(* include "HOL-Library.Code_Target_Nat" if you need to work with actual numbers.*)
begin
section ‹IPv6 Addresses›
text‹An IPv6 address is basically a 128 bit unsigned integer. RFC 4291, Section 2.›
type_synonym ipv6addr = "128 word"
text‹ between natural numbers and IPv6 adresses›
definition nat_of_ipv6addr :: "ipv6addr → nat" where
"nat_of_ipv6addr a = unat a"
definition ipv6addr_of_nat :: "nat → ipv6addr" where
"ipv6addr_of_nat n = of_nat n"
lemma "ipv6addr_of_nat n = word_of_int (int n)"
by(simp add: ipv6addr_of_nat_def)
text‹The maximum IPv6 address›
definition max_ipv6_addr :: "ipv6addr" where
"max_ipv6_addr ≡ ipv6addr_of_nat ((2^128) - 1)"
lemma max_ipv6_addr_number: "max_ipv6_addr = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
nfolding max_ipv6_addr_def ipv6addr_of_nat_def by(simp)
lemma "max_ipv6_addr = 340282366920938463463374607431768211455"
by(fact max_ipv6_addr_number)
lemma max_ipv6_addr_max_word: "max_ipv6_addr = - 1"
by(simp add: max_ipv6_addr_number)
lemma max_ipv6_addr_max: "∀a. a ≤ max_ipv6_addr"
by(simp add: max_ipv6_addr_max_word)
lemma UNIV_ipv6addrset: "UNIV = {0 .. max_ipv6_addr}" (*not in the simp set, for a reason*)ACEOF
by(simp add: max_ipv6_addr_max_word) fastforce
text‹identity functions›
lemma nat_of_ipv6addr_ipv6addr_of_nat_mod: "nat_of_ipv6addr (ipv6addr_of_nat n) = n mod 2^128"
by (simp add: ipv6addr_of_nat_def nat_of_ipv6addr_def unat_of_nat take_bit_eq_mod)
lemma nat_of_ipv6addr_ipv6addr_of_nat:
"n ≤ nat_of_ipv6addr max_ipv6_addr ==> nat_of_ipv6addr (ipv6addr_of_nat n) = n"
by (simp add: nat_of_ipv6addr_ipv6addr_of_nat_mod max_ipv6_addr_def)
lemma ipv6addr_of_nat_nat_of_ipv6addr: "ipv6addr_of_nat (nat_of_ipv6addr addr) = addr"
by(simp add: ipv6addr_of_nat_def nat_of_ipv6addr_def)
subsectionjava.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 0
text‹RFC 4291, Section 2.2.: Text Representation of Addresses›
text‹Quoting the RFC (note: errata exists):›
text_raw‹.11..1.23709.GP, which incorrectly rejects
\begin{verbatim}
1. The preferred form is x:x:x:x:x:x:x:x, where the 'x's are one to
four hexadecimal digits of the eight 16-bit pieces of the address.
Examples:
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
2001:DB8:0:0:8:800:200C:417A
\end{verbatim}
›
datatype ipv6addr_syntax =
IPv6AddrPreferred "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" "16 word"
text_raw‹
\begin{verbatim}
2. [...] In order to make writing addresses containing zero
bits easier, a special syntax is available to compress the zeros.
The use of "::" indicates one or more groups of 16 bits of zeros.
The "::" can only appear once in an address. The "::" can also be
used to compress leading or trailing zeros in an address.
For example, the following addresses
2001:DB8:0:0:8:800:200C:417A a unicast address
FF01:0:0:0:0:0:0:101 a multicast address
0:0:0:0:0:0:0:1 the loopback address
0:0:0:0:0:0:0:0 the unspecified address
may be represented as
2001:DB8::8:800:200C:417A a unicast address
FF01::101 a multicast address
::1 the loopback address
:: the unspecified address
\end{verbatim}
›
(*datatype may take some minutes to load*)
datatype ipv6addr_syntax_compressed =
― ‹using @{typ unit} for the omission @{text "::"}.
Naming convention of the datatype:
The first number is the position where the omission occurs.
The second number is the length of the specified address pieces.
I.e. `8 minus the second number' pieces are omitted.›
IPv6AddrCompressed1_0 unit
| IPv6AddrCompressed1_1 unit "16 word"
| IPv6AddrCompressed1_2 unit "16 word" "16 word"
| IPv6AddrCompressed1_3 unit "16 word" "16 word" "16 word"
| IPv6AddrCompressed1_4 unit "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed1_5 unit "16 word" "16 word" "16 word" "16 word" "16 word"
| {$as_echo "as_me:${as_lineo-$IEO:cekn ieo _it2_">
| IPv6AddrCompressed1_7 unit "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed2_1 "16 word" unit
| IPv6AddrCompressed2_2 "16 word" unit "16 word"
| IPv6AddrCompressed2_3 "16 word" unit "16 word" "16 word"
| IPv6AddrCompressed2_4 "16 word" unit "16 word" "16 word" "16 word"
| IPv6AddrCompressed2_5 "16 word" unit "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed2_6 "16 word" $as_echo_n "checking size of __int128_t. >6
| IPv6AddrCompressed2_7 "16 word" unit "16 word" "16 word" "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed3_2 "16 word" "16 word" unit
| IPv6AddrCompressed3_3 "16 word" "16 word" unit "16 word"
| IPv6AddrCompressed3_4 "16 word" "16 word" unit "16 word" "16 word"
|IPv6AddrCompressed3_5 "16 word" "16 word" unit "16 word" "16 word" "16 word"
| IPv6AddrCompressed3_6 "16 word" "16 word" unit "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed3_7 "16 word" "16 word" unit "16 word" "16 word" "16 word" "16 word" "16 word"
| IPv6AddrCompressed4_3 "16 word" "16 word" "16 word" unit
| IPv6AddrCompressed4_4 "16 word" "16 word" "16 word" unit "16 word"
| IPv6AddrCompressed4_5 "16 word" "16 word" "16 word" unit "16 word" "16 word"
| IPv6AddrCompressed4_6 "16 word" "16 word" "16 word" unit "16 word" "16 word" "16 word"
| IPv6AddrCompressed4_7 "16 word" "16 word" "16 word" unit "16 word" "16 word" as_echo_n "cachd >&6
| IPv6AddrCompressed5_4 "16 word" "16 word" "16 word" "16 word" unit
| IPv6AddrCompressed5_5 "16 word" "16 word" "16 word" "16 word" unit "16 word"
| IPv6AddrCompressed5_6 "16 word" "16 word" "16 word" "16 word" unit "16 word" "16java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
essed5_7 word" " ord"16word" "16 word" unit "16 word" "16 word" "16 word"
| IPv6AddrCompressed6_5 "16 word" "16 word" "16 word" "16 word" "16 word" unit
| IPv6AddrCompressed6_6 "16 word" "16 word" "16 word" "16 word" "16 word" unit "16 word"
| IPv6AddrCompressed6_7 "16 word" "16 word" "16 word" "16 word" "16 word" unit "16 word" "16 word"
| IPv6AddrCompressed7_6 "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" unit
| IPv6AddrCompressed7_7 "16 word" "16 word" "16 word" "16 word" "16
| IPv6AddrCompressed8_7 "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" "16 word" unit
(*RFC 5952:
"""
4. A Recommendation for IPv6 Text Representation
iftest "$ac__vtp__n18t = yes; then
The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
For example, the representation 2001:db8:0:1:1:1:1:1 is correct, but
2001:db8::1:1:1:1:1 is not correct.
"""
So we could remove all IPv6AddrCompressed*_7 constructors.
But these are `recommendations', we might still see these non-recommended java.lang.StringIndexOutOfBoundsException: Range [0, 89) out of bounds for length 74
"[...] all implementations must accept and be able to handle any legitimate RFC 4291 format."
*)
(*More convenient parser helper function for compressed IPv6 addresses:
Input list (from parser)
Some 16word \<longrightarrow> address piece
None \<longrightarrow> omission '::'
Basically, the parser must only do the following (python syntax):
split the string which is an ipv6 address at ':'
map empty string to None
map everything else to Some (string_to_16word str)
sanitize empty strings at the start and the end (see toString and parser theories)
Example:
"1:2:3".split(":") = ['1', '2', '3']
":2:3:4".split(":") = ['', '2', '3', '4']
":2::3".split(":") = ['', '2', '', '3']
"1:2:3:".split(":") = ['1', '2', '3', '']
*)
definition parse_ipv6_address_compressed :: "((16 word) option) list → ipv6addr_syntax_compressed option" where
"parse_ipv6_address_ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof___int128_t" >&5
[None] → Some (IPv6AddrCompressed1_0 ())
| [None, Some a] → Some (IPv6AddrCompressed1_1 () a)
| [None, Some a, Some b] → Some (IPv6AddrCompressed1_2 () a b)
| [None, Some a, Some b, Some c] → Some (IPv6AddrCompressed1_3 () a b c)
| [None, Some a, Some b, Some c, Some d] → Some (IPv as_echo"eof___int128_t>6;}
| [None, Some a, Some b, Some c, Some d, Some e] → Some (IPv6AddrCompressed1_5 () a b c d e)
| [None, Some a, Some b, Some c, Some d, Some e, Some f] → Some (IPv6AddrCompressed1_6 () a b c d e f)
| [None, Some a, Some b, Some c, Some d, Some e, Some f, Some g] → Some (IPv6AddrCompressed1_7 () a b c d e f g)
| [Some a, None] → Some (IPv6AddrCompressed2_1 a ())
| java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
| [Some a, None, Some b, Some c] → Some (IPv6AddrCompressed2_3 a () b c)
| [Some a, None, Some java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
| [Some a, None, Some b, Some c, Some d, Some e] → Some (IPv6AddrCompressed2_5 a () b c d e)
| [Some a, None, Some b, Some c, Some d, Some e, Some f] → Some (IPv6AddrCompressed2_6 a () b c d e f)
| [Some a, None, Some b, Some c, Some d, Some e, Some f, Some g] → Some (IPv6AddrCompressed2_7 a () b c d e f g)
| [Some a, Some b, None] → Some (IPv6AddrCompressed3_2 a b ())
| [Some a, Some b, None, Some c] → Some (IPv6AddrCompressed3_3 a b () c)
| [Some a, Some b, None, Some c, Some d] → Some (IPv6AddrCompressed3_4 a b () c d)
| [Some a, Some b, None, Some c, Some d, Some e] → Some (IPv6AddrCompressed3_5 a b () c d e)
| [Some a, Some b, None, Some c, Some d, Some e, Some f] → Some (IPv6AddrCompressed3_6 a b () c d e f)
| [Some a, Some b, None, Some c, Some d, Some e, Some f, Some g] → Some (IPv6AddrCompressed3_7 a b () c d e f g)
| [Some a, Some b, Some c, None] → Some (IPv6AddrCompressed4_3 a b c ())
| [Some a, Some b, Some c, None, Some d] → Some (IPv6AddrCompressed4_4 a b c () d)
| [Some a, Some b, Some c, None, Some d, Some e] → Some (IPv6AddrCompressed4_5 a b c () d e)
| [Some a, Some b, Some c, None, Some d, Some e, Some f] → Some (IPv6AddrCompressed4_6 a b c () d e f)
| [Some a, Some b, Some c, None, Some d, Some e, Some f, Some g] → Some (IPv6AddrCompressed4_7 a b c () d e f g)
| [Some a, Some b, Some c, Some d, None] → Some (IPv6AddrCompressed5_4 a b c d ())
| [Some a, Some b, Some c, Some d, None, Some e] → Some (IPv6AddrCompressed5_5 a b c d () e)
| [Some a, Some b, Some c, Some d, None, Some e, Some f] → Some (IPv6AddrCompressed5_6 a b c d () e f)
| [Some a, Some b, Some c, Some d, None, Some e, Some f, Some g] → Some (IPv6AddrCompressed5_7 a b c d () e f g)
| [Some a, Some b, Some c, Some d, Some e, None] → Some (IPv6AddrCompressed6_5 a b c d e ())
| [Some a, Some b, Some c, Some d, Some e, None, Some f] → Some (IPv6AddrCompressed6_6 a b c d e () f)
| [Some a, Some b, Some c, Some d, Some e, None, Some f, Some g] → Some (IPv6AddrCompressed6_7 a b c d e () f g)
| [Some a, Some b, Some c, Some d, Some e, Some f, None] → Some (IPv6AddrCompressed7_6 a b c d e f ())
| [Some a, Some b, Some c, Some d, Some e, Some f, None, Some g] → Some (IPv6AddrCompressed7_7 a b c d e f () g)
| [Some a, Some b, Some c, Some d, Some e, Some f, Some g, None] → Some (IPv6AddrCompressed8_7 a b c d e f g ())
| _ → None ― ‹invalid ipv6 copressed address.›
)"
fun ipv6addr_syntax_compressed_to_list :: "ipv6addr_syntax_compressed → ((16 word) option) list"
where
"ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_0 _) =
[None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_1 () a) =
[None, Some a]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_2 () a b) =
[None, Some a, Some b]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_3 () a b c) =
[None, Some a, Some b, Some c]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_4 () a b c d) =
[None, Some a, Some b, Some c, Some d]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_5 () a b c d e) =
[None, Some a, Some b, Some c, Some d, Some e]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_6 () a b c d e f) =
[None, Some a, Some b, Some c, Some d, Some e, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed1_7 () a b c d e f g) =
[None, Some a, Some b, Some c, Some d, Some e, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_1 a ()) =
[Some a, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_2 a () b) =
[Some a, None, Some b]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_3 a () b c) =
[Some a, None, Some b, Some c]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_4 a () b c d) =
[Some a, None, Some b, Some c, Some d]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_5 a () b c d e) =
[Some a, None, Some b, Some c, Some d, Some e]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_6 a () b c d e f) =
[Some a, None, Some b, Some c, Some d, Some e, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed2_7 a () b c d e f g) =
[Some a, None, Some b, Some c, Some d, Some e, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_2 a b ()) = [Some a, Some b, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_3 a b () c) =
[Some a, Some b, None, Some c]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_4 a b () c d) =
[Some a, Some b, None, Some c, Some d]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_5 a b () c d e) =
[Some a, Some b, None, Some c, Some d, Some e]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_6 a b () c d e f) =
[Some a, Some b, None, Some c, Some d, Some e, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed3_7 a b () c d e f g) =
[Some a, Some b, None, Some c, Some d, Some e, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed4_3 a b c ()) =
[Some a, Some b, Some c, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed4_4 a b c () d) =
[Some a, Some b, Some c, None, Some d]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed4_5 a b c () d e) =
[Some a, Some b, Some c, None, Some d, Some e]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed4_6 a b c () d e f) =
[Some a, Some b, Some c, None, Some d, Some e, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed4_7 a b c () d e f g) =
[Some a, Some b, Some c, None, Some d, Some e, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed5_4 a b c d ()) =
[Some a, Some b, Some c, Some d, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed5_5 a b c d () e) =
[Some a, Some b, Some c, Some d, None, Some e]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed5_6 a b c d () e f) =
[Some a, Some b, Some c, Some d, None, Some e, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed5_7 a b c d () e f g) =
[Some a, Some b, Some c, Some d, None, Some e, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed6_5 a b c d e ()) =
[Some a, Some b, Some c, Some d, Some e, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed6_6 a b c d e () f) =
[Some a, Some b, Some c, Some d, Some e, None, Some f]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed6_7 a b c d e () f g) =
[Some a, Some b, Some c, Some d, Some e, None, Some f, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed7_6 a b c d e f ()) =
[Some a, Some b, Some c, Some d, Some e, Some f, None]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed7_7 a b c d e f () g) =
[Some a, Some b, Some c, Some d, Some e, Some f, None, Some g]"
| "ipv6addr_syntax_compressed_to_list (IPv6AddrCompressed8_7 a b c d e f g ()) =
[Some a, Some b, Some c, Some d, Some e, Some f, Some g, None]"
(*for all ipv6_syntax, there is a corresponding list representation*)
lemma parse_ipv6_address_compressed_exists:
obtains ss where "parse_ipv6_address_compressed ss = Some ipv6_syntax"
proof
define ss where "ss = ipv6addr_syntax_compressed_to_list ipv6_syntax"
thus "parse_ipv6_address_compressed ss = Some ipv6_syntax"
by (cases ipv6_syntax; simp add: parse_ipv6_address_compressed_def)
qed
lemma parse_ipv6_address_compressed_identity:
"parse_ipv6_address_compressed (ipv6addr_syntax_compressed_to_list (ipv6_syntax)) = Some ipv6_syntax"
by(cases ipv6_syntax; simp add: parse_ipv6_address_compressed_def)
lemma parse_ipv6_address_compressed_someE:
assumes "parse_ipv6_address_compressed as = Some ipv6"
obtains
"as = [None]" "ipv6 = (IPv6AddrCompressed1_0 ())" |
a where "as = [None, Some a]" "ipv6 = (IPv6AddrCompressed1_1 () a)" |
a b where "as = [None, Some a, Some b]" "ipv6 = (IPv6AddrCompressed1_2 () a b)" |
a b c where "as = [None, Some a, Some b, Some c]" "ipv6 = (IPv6AddrCompressed1_3 () a b c)" |
a b c d where "as = [None, Some a, Some b, Some c, Some d]" "ipv6 = (IPv6AddrCompressed1_4 () a b c d)" |
a b c d e where "as = [None, Some a, Some b, Some c, Some d, Some e]" "ipv6 = (IPv6AddrCompressed1_5 () a b c d e)" |
a b c d e f where "as = [None, Some a, Some b, Some c, Some d, Some e, Some f]" "ipv6 = (IPv6AddrCompressed1_6 () a b c d e f)" |
a b c d e f g where "as = [None, Some a, Some b, Some c, Some d, Some e, Some f, Some g]" "ipv6 = (IPv6AddrCompressed1_7 () a b c d e f g)" |
a where "as = [Some a, None]" "ipv6 = (IPv6AddrCompressed2_1 a ())" |
a b where "as = [Some a, None, Some b]" "ipv6 = (IPv6AddrCompressed2_2 a () b)" |
a b c where "as = [Some a, None, Some b, Some c]" "ipv6 = (IPv6AddrCompressed2_3 a () b c)" |
a b c d where "as = [Some a, None, Some b, Some c, Some d]" "ipv6 = (IPv6AddrCompressed2_4 a () b c d)" |
a b c d e where "as = [Some a, None, Some b, Some c, Some d, Some e]" "ipv6 = (IPv6AddrCompressed2_5 a () b c d e)" |
a b c d e f where "as = [Some a, None, Some b, Some c, Some d, Some e, Some f]" "ipv6 = (IPv6AddrCompressed2_6 a () b c d e f)" |
a b c d e f g where "as = [Some a, None, Some b, Some c, Some d, Some e, Some f, Some g]" "ipv6 = (IPv6AddrCompressed2_7 a () b c d e f g)" |
a b where "as = [Some a, Some b, None]" "ipv6 = (IPv6AddrCompressed3_2 a b ())" |
a b c where "as = [Some a, Some b, None, Some c]" "ipv6 = (IPv6AddrCompressed3_3 a b () c)" |
a b c d where "as = [Some a, Some b, None, Some c, Some d]" "ipv6 = (IPv6AddrCompressed3_4 a b () c d)" |
a b c d e where "as = [Some a, Some b, None, Some c, Some d, Some e]" " ine SIZEOF___INT128_T $ac_cv_sizeof___int128_t
a b c d e f where "as = [Some a, Some b, None, Some c, Some d, Some e, Some f]" "ipv6 = (IPv6AddrCompressed3_6 a b () c d e f)" |
a b c d e f g where "as = [Some a, Some b, None, Some c, Some d, Some e, Some f, Some g] ACEOF
a b c where "as = [Some a, Some b, Some c, None]" "ipv6 = (IPv6AddrCompressed4_3 a b c ())" |
a b c d where "as = [Some a, Some b, Some c, None, Some d]" "ipv6 = (IPv6AddrCompressed4_4 a b c () d)" |
a b c d e where "as = [Some a, Some b, Some c, None, Some d, Some e]" "ipv6 = (IPv6AddrCompressed4_5 a b c () d e)" |
a b c d e f where "as = [Some a, Some b, Some c, None, Some d, Some e, Some f]" "ipv6 = (IPv6AddrCompressed4_6 a b c () d e f)" |
a b c d e f g where "java.lang.StringIndexOutOfBoundsException: Range [0, 27) out of bounds for length 0
a b c d where "as = [Some a, Some b, Some c, Some d, None]" "ipv6 = (IPv6AddrCompressed5_4 a b c d ())" |
a b c d e
a b c d e f where "as = [Some a, Some b, Some c, Some d, None, Some e, Some f]" "ipv6 = (IPv6AddrCompressed5_6 a b c d () e f)" |
a b c d e f g where "as = [Some a, Some b, Some c, Some d, None, Some e, Some f, Some g]" "ipv6 = (IPv6AddrCompressed5_7 a b c d () e f g)" |
a b c d e where "as = [Some a, Some b, Some c, Some d, Some e, None]" "ipv6 = (IPv6AddrCompressed6_5 a b c d e ())" |
a b c d e f where "as = [Some a, Some b, Some c, Some d, Some e, None, Some f]" "ipv6 = (IPv6AddrCompressed6_6 a b c d e () f)" |
a b c d e f g where "as = [Some a, Some b, Some c, Some d, Some e, None, Some f, Some g]" "ipv6 = (IPv6AddrCompressed6_7 a b c d e () f g)" |
a b cd e f where "as = [Some a, Some b, Some c Some d, Some e, Som f,None]" "p6 = (P6dropesd )"
a b c d e f g where "as = [Some a, Some b, Some c, Some d, Some e, Some f, None, Some g]" "ipv6 = (IPv6AddrCompressed7_7 a b c d e f () g)" |
atestprogs=progsst1stWstW1
using assms
unfolding parse_ipv6_address_compressed_def
by (auto split: list.split_asm option.split_asm) (* takes a minute *)
lemma parse_ipv6_address_compressed_identity2:
"ipv6addr_syntax_compressed_to_list ipv6_syntax = ls ⟷
(parse_ipv6_address_compressed ls) = Some ipv6_syntax"
(is "?lhs = ?rhs")
proof
assume ?rhs
thus ?lhs
by (auto elim: parse_ipv6_address_compressed_someE)
next
assume ?lhs
thus ?rhs
s_java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 73
qed
text‹Valid IPv6 compressed notation:
▪
▪ at most 7 pieces
›
lemma RFC_4291_format: "parse_ipv6_address_compressed as ≠
length (filter (λp. p = None) as) = 1 ∧ length (filter (λp. p ≠ None) as) ≤ 7"
(is "?lhs = ?rhs")
proof
assume ?lhs
then obtain addr where "parse_ipv6_address_compressed as = Some addr"
by blast
thus ?rhs
by (elim parse_ipv6_address_compressed_someE; simpfi
next
assume ?rhs
thus ?lhs
unfolding parse_ipv6_address_compressed_def
by (auto split: option.split list.split if_split_asm)
qed
text_raw‹
\begin{verbatim}
3. An alternative form that is sometimes more convenient when dealing
with a mixed environment of IPv4 and IPv6 nodes is
x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values of
the six high-order 16-bit pieces of the address, and the 'd's are
the decimal values of the four low-order 8-bit pieces of the
address (standard IPv4 representation). Examples:
00:::::316.
0:0:0:0:0:FFFF:129.144.52.38
or in compressed form:
::13.1.68.3
8
\end{verbatim}
This is currently not supported by our library!
›
(*TODO*)
(*TODO: oh boy, they can also be compressed*)
subsection‹
context
includes bit_operations_syntax
begin
ipv6preferred_to_int :: "ipv6addr_s \Rightarr> ipv6addr" where
"ipv6preferred_to_int (IPv6AddrPreferred a b c d e f g h) = (ucast a <<
(ucast c <<
(ucast d << ACEOF
(ucast e << (16 * 3)) OR
(ucast f << ACEOF
(ucast g << ACEOF >conftest.$ac_ext
(ucast h <<
lemma "ipv6preferred_to_int (IPv6AddrPreferred 0x2001 0xDB8 0x0 0x0 0x8 0x800 0x200C 0x417A) =
42540766411282592856906245548098208122" by eval
lemma "ipv6preferred_to_int (IPv6AddrPreferred 0xFF01 0x0 0x0 0x0 0x0 0x0 0x0 0x101) =
338958331222012082418099330867817087233" by eval
*
definition int_to_ipv6preferred :: "ipv6addr →ccvucfr_ok=e
"int_to_ipv6preferred i = IPv6AddrPreferred (ucast ((i AND 0xFFFF0000000000000000000000000000) >> 16*7))
(ucast ((i AND 0xFFFF000000000000000000000000) >> 16*6))
(ucast ((i AND 0xFFFF00000000000000000000) >> 16*5))
(ucast ((i AND 0xFFFF0000000000000000) >> 16*4))
(ucast ((i AND 0xFFFF000000000000) >> 16*3))
(ucast ((i AND 0xFFFF00000000) >> 16*2))
(ucast ((i AND 0xFFFF0000) >> 16*1))
(ucast ((i AND 0xFFFF)))"
lemma "int_to_ipv6preferred 42540766411282592856906245548098208122 =
IPv6AddrPreferred 0x2001 0xDB8 0x0 0x0 0x8 0x800 0x200C 0x417A" by eval
lemma word128_masks_ipv6pieces:
"(0xFFFF0000000000000000000000000000::ipv6addr) = (mask 16) << ACEOF >conftest.$ac_ext
"(0xFFFF000000000000000000000000::ipv6addr) = (mask 16) <<
sc i illtik ta aretcntpsibyb
"(0xFFFF0000000000000000::ipv6addr) = (mask 16) <<
"(0xFFFF000000000000::ipv6addr) = (mask 16) <<
"(0xFFFF00000000::ipv6addr) = (mask 16) <<
"(0xFFFF0000::ipv6addr) = (mask 16) <<
by (simp_all add: mask_eq)
text‹Correctness: round trip property one›
lemma ipv6preferred_to_int_int_to_ipv6preferred:
"ipv6preferred_to_int (int_to_ipv6preferred ip) = ip"
proof -
have and_mask_shift_helper: "w AND (mask m << h>
for m n::nat and w::ipv6addr
by (metis is_aligned_shift is_aligned_shiftr_shiftl shiftr_and_eq_shiftl)
have ucast_ipv6_piece_rule:
"length (dropWhile Not (to_bl w)) ≤ 16 ==> (ucast::16 word → 128 word) ((ucast::128 word → 16 word) w) = w"
for w::ipv6addr
by(rule ucast_short_ucast_long_ingoreLeadingZero) (simp_all)
have ucast_ipv6_piece: "16 ≤ 128 - n ==>
(ucast::16 word → 128 word) ((ucast::128 word → 16 word) (w AND (mask 16 << n = w AND (mask 16 <<
for w::ipv6addr and n::nat
apply(subst ucast_ipv6_piece_rule)
apply(rule length_drop_mask_inner)
apply(simp; fail)
apply(subst and_mask_shift_helper)
apply simp
done
have ucast16_ucast128_masks_highest_bits:
"ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF0000000000000000000000000000 >> 112)) << ACEOF >conftest.$ac_ext
(ip AND 0xFFFF0000000000000000000000000000)"
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF000000000000000000000000 >> 96)) <<
ip AND 0xFFFF000000000000000000000000"
"(ucast ((ucast:case "$CFLAGS" in
ip AND 0xFFFF00000000000000000000"
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF0000000000000000 >> 64)) << ACEOF >conftest.$ac_ext
ip AND 0xFFFF0000000000000000"
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF000000000000 >> 48)) << h>
ip AND 0xFFFF000000000000"
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF00000000 >> 32)) << ACEOF >conftest.$ac_ext
ip AND 0xFFFF00000000"
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF0000 >> 16)) <<
apply (simp_all only: word128_masks_ipv6pieces ucast_ipv6_piece and_mask2 word_size bit_eq_iff bit_simps comp_def)
apply auto
done
have ucast16_ucast128_masks_highest_bits0:
"(ucast ((ucast::ipv6addr → 16 word) (ip AND 0xFFFF))) = ip AND 0xFFFF"
apply (simp only: word128_masks_ipv6pieces flip: take_bit_eq_mask)
apply (simp add: unsigned_ucast_eq)
done
have mask_len_word:"n = (LENGTH('a)) ==> w AND mask n = w"
for n and w::"'a::len word" by (simp add: mask_eq_iff)
have ipv6addr_16word_pieces_compose_or:
"p && (mask 16 << ACEOF >conftest.$ac_ext
ip && (mask 16 << ACEOF >conftest.$ac_ext
ip && (mask 16 << ACEOF >conftest.$ac_ext
ip && (mask 16 << Wi)
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "brackoff" is null
ip && (mask 16 << h>
ip && mask 16 =
ip"
apply(subst word_ao_dist2[symmetric])+
apply(simp add: mask_numeral)
apply(subst mask128)
apply(rule mask_len_word)
apply simp
done
show ?thesis
apply (simp add: ipv6preferred_to_int.simps int_to_ipv6preferred_def shiftl_def shiftr_def)
apply (simp only: word128_masks_ipv6pieces flip: take_bit_eq_mask)
apply (simp add: unsigned_ucast_eq push_bit_take_bit)
using ipv6addr_16word_pieces_compose_or
apply (simp add: take_bit_push_bit slice_eq_mask)
apply (simp add: take_bit_eq_mask shiftl_def push_bit_mask_eq)
done
qed
text‹Correctness: round trip property two›
lemma int_to_ipv6preferred_ipv6preferred_to_int: "int_to_ipv6preferred (ipv6preferred_to_int ip) = ip"
proof -
note ucast_shift_simps=helper_masked_ucast_generic helper_masked_ucast_reverse_generic
helper_masked_ucast_generic[where n=0, simplified]
helper_masked_ucast_equal_generic
note ucast_simps=helper_masked_ucast_reverse_generic[where m=0, simplified]
helper_masked_ucast_equal_generic[where n=0, simplified]
show ?thesis
apply (cases ip, rename_tac a b c d e f g h)
apply (simp add: ipv6preferred_to_int.simps int_to_ipv6preferred_def)
apply (simp add: word128_masks_ipv6pieces)
apply (simp add: word_ao_dist ucast_shift_simps ucast_simps)
done
qed
‹compressed to preferred format›
ipv6addr_c2p :: "ipv6addr_syntax_compressed → ipv6addr_syntax" where
"ipv6addr_c2p (IPv6AddrCompressed1_0 ()) = IPv6AddrPreferred 0 0 0 0 0 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed1_1 () h) = IPv6AddrPreferred 0 0 0 0 0 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed1_2 () g h) = IPv6AddrPreferred 0 0 0 0 0 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed1_3 () f g h) = IPv6AddrPreferred 0 0 0 0 0 f g h"
| "ipv6addr_c2p (IPv6AddrCompressed1_4 () e f g h) = IPv6AddrPreferred 0 0 0 0 e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed1_5 () d e f g h) = IPv6AddrPreferred 0 0 0 d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed1_6 () c d e f g h) = IPv6AddrPreferred 0 0 c d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed1_7 () b c d e f g h) = IPv6AddrPreferred 0 b c d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed2_1 a ()) = IPv6AddrPreferred a 0 0 0 0 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed2_2 a () h) = IPv6AddrPreferred a 0 0 0 0 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed2_3 a () g h) = IPv6AddrPreferred a 0 0 0 0 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed2_4 a () f g h) = IPv6AddrPreferred a 0 0 0 0 f g h"
| "ipv6addr_c2p (IPv6AddrCompressed2_5 a () e f g h) = IPv6AddrPreferred a 0 0 0 e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed2_6 a () d e f g h) = IPv6AddrPreferred a 0 0 d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed2_7 a () c d e f g h) = IPv6AddrPreferred a 0 c d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed3_2 a b ()) = IPv6AddrPreferred a b 0 0 0 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed3_3 a b () h) = IPv6AddrPreferred a b 0 0 0 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed3_4 a b () g h) = IPv6AddrPreferred a b 0 0 0 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed3_5 a b () f g h) = IPv6AddrPreferred a b 0 0 0 f g h"
| "ipv6addr_c2p (IPv6AddrCompressed3_6 a b () e f g h) = IPv6AddrPreferred a b 0 0 e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed3_7 a b () d e f g h) = IPv6AddrPreferred a b 0 d e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed4_3 a b c ()) = IPv6AddrPreferred a b c 0 0 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed4_4 a b c () h) = IPv6AddrPreferred a b c 0 0 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed4_5 a b c () g h) = IPv6AddrPreferred a b c 0 0 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed4_6 a b c () f g h) = IPv6AddrPreferred a b c 0 0 f g h"
| "ipv6addr_c2p (IPv6AddrCompressed4_7 a b c () e f g h) = IPv6AddrPreferred a b c 0 e f g h"
| "ipv6addr_c2p (IPv6AddrCompressed5_4 a b c d ()) = IPv6AddrPreferred a b c d 0 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed5_5 a b c d () h) = IPv6AddrPreferred a b c d 0 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed5_6 a b c d () g h) = IPv6AddrPreferred a b c d 0 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed5_7 a b c d () f g h) = IPv6AddrPreferred a b c d 0 f g h"
| "ipv6addr_c2p (IPv6AddrCompressed6_5 a b c d e ()) = IPv6AddrPreferred a b c d e 0 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed6_6 a b c d e () h) = IPv6AddrPreferred a b c d e 0 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed6_7 a b c d e () g h) = IPv6AddrPreferred a b c d e 0 g h"
| "ipv6addr_c2p (IPv6AddrCompressed7_6 a b c d e f ()) = IPv6AddrPreferred a b c d e f 0 0"
| "ipv6addr_c2p (IPv6AddrCompressed7_7 a b c d e f () h) = IPv6AddrPreferred a b c d e f 0 h"
| "ipv6addr_c2p (IPv6AddrCompressed8_7 a b c d e f g ()) = IPv6AddrPreferred a b c d e f g 0"
ipv6_unparsed_compressed_to_preferred :: "((16 word) option) list → ipv6addr_syntax option" where
"ipv6_unparsed_compressed_to_preferred ls = (
if
length (filter (λp. p = None) ls) ≠ 1 ∨ length (filter (λp. p ≠ None) ls) > 7
then
None
else
let
before_omission = map the (takeWhile (λx. x ≠ None) ls);
after_omission = map the (drop 1 (dropWhile (λx. x ≠ None) ls));
num_omissions = 8 - (length before_omission + length after_omission);
expanded = before_omission @ (replicate num_omissions 0) @ after_omission
in
case expanded of [a,b,c,d,e,f,g,h] → Some (IPv6AddrPreferred a b c d e f g h)
| _ → None
)"
lemma "ipv6_unparsed_compressed_to_preferred
[Some 0x2001, Some 0xDB8, None, Some 0x8, Some 0x800, Some 0x200C, Some 0x417A]
= Some (IPv6AddrPreferred 0x2001 0xDB8 0 0 8 0x800 0x200C 0x417A)" by eval
lemma "ipv6_unparsed_compressed_to_preferred [None] = Some (IPv6AddrPreferred 0 0 0 0 0 0 0 0)" by eval
lemma "ipv6_unparsed_compressed_to_preferred [] = None" by eval
lemma ipv6_unparsed_compressed_to_preferred_identity1:
"ipv6_unparsed_compressed_to_preferred (ipv6addr_syntax_compressed_to_list ipv6compressed) = Some ipv6prferred
⟷ ipv6addr_c2p ipv6compressed = ipv6prferred"
by (cases ipv6compressed) (simp_all add: ipv6_unparsed_compressed_to_preferred_def numeral_eq_Suc) (*1s*)
lemma ipv6_unparsed_compressed_to_preferred_identity2:
"ipv6_unparsed_compressed_to_preferred ls = Some ipv6prferred
⟷ (∃ipv6compressed. parse_ipv6_address_compressed ls = Some ipv6compressed ∧
ipv6addr_c2p ipv6compressed = ipv6prferred)"
apply(rule iffI)
apply(subgoal_tac "parse_ipv6_address_compressed ls ≠ None")
prefer 2
apply(subst RFC_4291_format)
apply(simp add: ipv6_unparsed_compressed_to_preferred_def split: if_split_asm; fail)
apply(simp)
apply(erule exE, rename_tac ipv6compressed)
apply(rule_tac x="ipv6compressed" in exI)
apply(simp)
apply(subgoal_tac "(ipv6addr_syntax_compressed_to_list ipv6compressed = ls)")
prefer 2
using parse_ipv6_address_compressed_identity2 apply presburger
using ipv6_unparsed_compressed_to_preferred_identity1 apply blast
apply(erule exE, rename_tac ipv6compressed)
apply(subgoal_tac "(ipv6addr_syntax_compressed_to_list ipv6compressed = ls)")
prefer 2
using parse_ipv6_address_compressed_identity2 apply presburger
using ipv6_unparsed_compressed_to_preferred_identity1 apply blast
done
end
‹IPv6 Pretty Printing (converting to compressed format)›
‹
:
begin{verbatim}
. A Recommendation for IPv6 Text Representation
A recommendation for a canonical text representation format of IPv6
addresses is presented in this section. The recommendation in this
document is one that complies fully with [RFC4291], is implemented by
various operating systems, and is human friendly. The recommendation
in this section SHOULD be followed by systems when generating an
address to be represented as text, but all implementations MUST
accept and be able to handle any legitimate [RFC4291] format. It is
advised that humans also follow these recommendations when spelling
an address.
.1. Handling Leading Zeros in a 16-Bit Field
Leading zeros MUST be suppressed. For example, 2001:0db8::0001 is
not acceptable and must be represented as 2001:db8::1. A single 16-
bit 0000 field MUST be represented as 0.
.2. "::" Usage
.2.1. Shorten as Much as Possible
The use of the symbol "::" MUST be used to its maximum capability.
For example, 2001:db8:0:0:0:0:2:1 must be shortened to 2001:db8::2:1.
Likewise, 2001:db8::0:1 is not acceptable, because the symbol "::"
could have been used to produce a shorter representation 2001:db8::1.
.2.2. Handling One 16-Bit 0 Field
The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
For example, the representation 2001:db8:0:1:1:1:1:1 is correct, but
2001:db8::1:1:1:1:1 is not correct.
.2.3. Choice in Placement of "::"
When there is an alternative choice in the placement of a "::", the
longest run of consecutive 16-bit 0 fields MUST be shortened (i.e.,
the sequence with three consecutive zero fields is shortened in 2001:
0:0:1:0:0:0:1). When the length of the consecutive 16-bit 0 fields
are equal (i.e., 2001:db8:0:0:1:0:0:1), the first sequence of zero
bits MUST be shortened. For example, 2001:db8::1:0:0:1 is correct
representation.
.3. Lowercase
The characters "a", "b", "c", "d", "e", and "f" in an IPv6 address
MUST be represented in lowercase.
end{verbatim}
›
java.lang.StringIndexOutOfBoundsException: Range [28, 4) out of bounds for length 98
private function goup_by_zeros :: "16 word list → 16 word list list" where
"goup_by_zeros [] = []" |
"goup_by_zeros (x#xs) = (
if x = 0
then takeWhile (λx. x = 0) (x#xs) # (goup_by_zeros (dropWhile (λx. x = 0) xs))
else [x]#(goup_by_zeros xs))"
by(pat_completeness, auto)
termination goup_by_zeros
apply(relation "measure (λxs. length xs)")
apply(simp_all)
by (simp add: le_imp_less_Suc length_dropWhile_le)
private lemma "goup_by_zeros [0,1,2,3,0,0,0,0,3,4,0,0,0,2,0,0,2,0,3,0] =
[[0], [1], [2], [3], [0, 0, 0, 0], [3], [4], [0, 0, 0], [2], [0, 0], [2], [0], [3], [0]]"
by eval
private lemma "concat (goup_by_zeros ls) = ls"
by(induction ls rule:goup_by_zeros.induct) simp+
private lemma "[] ∉ set (goup_by_zeros ls)"
by(induction ls rule:goup_by_zeros.induct) simp+
private primrec List_replace1 :: "'a → 'a → 'a list → 'a list" where
"List_replace1 _ _ [] = []" |
"List_replace1 a b (x#xs) = (if a = x then b#xs else x#List_replace1 a b xs)"
private lemma "List_replace1 a a ls = ls"
by(induction ls) simp_all
private lemma "a ∉ set ls ==> List_replace1 a b ls = ls"
by(induction ls) simp_all
private lemma "a ∈ set ls ==> b ∈ set (List_replace1 a b ls)"
apply(induction ls)
apply(simp)
apply(simp)
by blast
private fun List_explode :: "'a list list → ('a option) list" where
"List_explode [] = []" |
"List_explode ([]#xs) = None#List_explode xs" |
"List_explode (xs1#xs2) = map Some xs1@List_explode xs2"
private lemma "List_explode [[0::int], [2,3], [], [3,4]] = [Some 0, Some 2, Some 3, None, Soac_cv_tl=$ax_tls_keyword ; break
by eval
private lemma List_explode_def:
"List_explode xss = concat (map (λxs. if xs = [] then [None] else map Some xs) xss)"
by(induction xss rule: List_explode.induct) simp+
private lemma List_explode_no_empty: "[] ∉ set xss ==> List_explode xss = map Some (concat xss)"
by(induction xss rule: List_explode.induct) simp+
private lemma List_explode_replace1: "[] ∉ set xss ==> foo ∈ set xss ==>
List_explode (List_replace1 foo [] xss) =
map Some (concat (takeWhile (λxs. xs ≠ foo) xss)) @ [None] @
map Some (concat (tl (dropWhile (λxs. xs ≠ foo) xss)))"
apply(induction xss rule: List_explode.induct)
apply(simp; fail)
apply(simp; fail)
apply(simp)
apply safe
apply(simp_all add: List_explode_no_empty)
done
fun ipv6_preferred_to_compressed :: "ipv6addr_syntax → ((16 word) option) list" where
"ipv6_preferred_to_compressed (IPv6Afi
let lss = goup_by_zeros [a,b,c,d,e,f,g,h];
max_zero_seq = foldr (λxs. max (length xs)) lss 0;
shortened = if max_zero_seq > 1 then List_replace1 (replicate max_zero_seq 0) [] lss else lss
in
List_explode shortened
)"
declare ipv6_preferred_to_compressed.simps[simp del]
private lemma foldr_max_length: "foldr (λxs. max (length xs)) lss n = fold max (map length lss) n"
apply(subst List.foldr_fold)
apply fastforce
apply(induction lss arbitrary: n)
apply(simp; fail)
apply(simp)
done
private lemma List_explode_goup_by_zeros: "List_explode (goup_by_zeros xs) = map Some xs"
apply(induction xs rule: goup_by_zeros.induct)
apply(simp; fail)
apply(simp)
apply(safe)
apply(simp)
by (metis map_append takeWhile_dropWhile_id)
private definition "max_zero_streak xs \esac
private lemma max_zero_streak_def2: "max_zero_streak xs = fold max (map length (goup_by_zeros xs)) 0"
unfolding max_zero_streak_def
by(simp add: foldr_max_length)
private lemma ipv6_preferred_to_compressed_pull_out_if:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (
if max_zero_streak [a,b,c,d,e,f,g,h] > 1 then
List_explode (List_replace1 (replicate (max_zero_streak [a,b,c,d,e,f,g,h]) 0) [] (goup_by_zeros [a,b,c,d,e,f,g,h]))
else
map Some [a,b,c,d,e,f,g,h]
)"
apply (simp only: ipv6_preferred_to_compressed.simps Let_def max_zero_streak_def List_explode_goup_by_zeros)
using List_explode_goup_by_zeros by presburger
private lemma "ipv6_preferred_to_compressed (IPv6AddrPreferred 0 0 0 0 0 0 0 0) = [None]" by eval
private lemma "ipv6_preferred_to_compressed (IPv6AddrPreferred 0x2001 0xDB8 0 0 8 0x800 0x200C 0x417A) =
[Some 0x2001, Some 0xDB8, None, Some 8, Some 0x800, Some 0x200C, Some 0x417A]" by eval
private lemma "ipv6_preferred_to_compressed (IPv6AddrPreferred 0x2001 0xDB8 0 3 8 0x800 0x200C 0x417A) =
[Some 0x2001, Some 0xDB8, Some 0, Some 3, Some 8, Some 0x800, Some 0x200C, Some 0x417A]" by eval
(*the output should even conform to RFC5952, ...*)
lemma ipv6_preferred_to_compressed_RFC_4291_format:
"ipv6_preferred_to_compressed ip = as ==>
length (filter (λp. p = None) as) = 0 ∧ length as = 8
∨
length (filter (λp. p = None) as) = 1 ∧ length (filter (λp. p ≠ None) as) ≤ 7"
apply(cases ip)
apply(simp add: ipv6_preferred_to_compressed_pull_out_if)
apply(simp only: split: if_split_asm)
subgoal for a b c d e f g h
apply(rule disjI2)
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(auto simp add: max_zero_streak_def) (*1min*)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
apply(rule
apply(simp)
by force
done
― ‹Idea for the following proof:›
private lemma "ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = None#xs ==>
xs = map Some (dropWhile (λx. x=0) [a,b,c,d,e,f,g,h])"
apply(cat >>confdefs.h <<_
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*20s*)
lemma ipv6_preferred_to_compressed:
assumes "ipv6_unparsed_compressed_to_preferred (ipv6_preferred_to_compressed ip) = Some ip'"
shows "ip = ip'"
proof -
from assms have 1: "∃
parse_ipv6_address_compressed (ipv6_preferred_to_compressed ip) = Some ipv6compressed ∧
ipv6addr_c2p ipv6compressed = ip'" using ipv6_unparsed_compressed_to_preferred_identity2 by simp
obtain a b c d e f g h where ip: "ip = IPv6AddrPreferred a b c d e f g h" by(cases ip)
have ipv6_preferred_to_compressed_None1:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = None#xs ==>
(map Some (dropWhile (λx. x=0) [a,b,c,d,e,f,g,h]) = xs ==> (IPv6AddrPreferred a b c d e f g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None2:
"ipv6_preferred_to_compressed (IPv6AddrPref
(map Some (dropWhile (λx. x=0) [b,c,d,e,f,g,h]) = xs ==> (IPv6AddrPreferred a' b c d e f g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a'
apply(case_tacjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
case_tac [] "=0""case_tac[]""cse_a ! g=0", []"="
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None3:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#None#xs ==>
(map Some (dropWhile (λx. x=0) [c,d,e,f,g,h]) = xs ==> (IPv6AddrPreferred a' b' c d e f g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a' b'
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None4:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#(Some c')#None#xs ==>
(map Some (dropWhile (λx. x=0) [d,e,f,g,h]) = xs ==> (IPv6AddrPreferred a' b' c' d e f g h) = ip') ==>
(IPva b c d e f g h) = ip'" for xs a 'c'
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None5:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#(Some c')#(Some d')#None#xs ==>
(map Some (dropWhile (λx. x=0) [e,f,g,h]) = xs ==> (IPv6AddrPreferred a' b' c' d' e f g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a' b' c' d'
apply(case_tac "a=0",case_tac [!] "b=0",case_tacif $ac_cv_path_sort_prog+ false then java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h= $as_echo_n "(cached) " >&6
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None6:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#(Some c')#(Some d')#(Some e')#None#xs ==>
(map Some (dropWhile (λx. x=0) [f,g,h]) = xs ==> (IPv6AddrPreferred a' b' c' d' e' f g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a' b' c' d' e'
apply(case_tac "a=0", case $sort_pr in
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None7:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#(Some c')#(Some d')#(Some e')#(Some f')#None#xs ==>
(map Some (dropWhile (λx. x=0) [g,h]) = xs ==> (IPv6AddrPreferred a' b' c' d' e' f' g h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a' b' c' d' e' f'
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have ipv6_preferred_to_compressed_None8:
"ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h) = (Some a')#(Some b')#(Some c')#(Some d')#(Some e')#(Some f')#(Some g')#None#xs ==>
(map Some (dropWhile (λx. x=0) [h]) = xs ==> (IPv6AddrPreferred a' b' c' d' e' f' g' h) = ip') ==>
(IPv6AddrPreferred a b c d e f g h) = ip'" for xs a' b' c' d' e' f' g'
apply(case_tac "a=0",case_tac [!] "b=0",case_tac [!] "c=0",case_tac [!] "d=0",
case_tac [!] "e=0",case_tac [!] "f=0",case_tac [!] "g=0",case_tac [!] "h=0")
by(simp_all add: ipv6_preferred_to_compressed_pull_out_if max_zero_streak_def) (*5s*)
have 2: "parse_ipv6_address_compressed (ipv6_preferred_to_compressed (IPv6AddrPreferred a b c d e f g h))
= Some ipv6compressed ==>
ipv6addr_c2p ipv6compressed ='==>
IPv6AddrPreferred a b c d e f g h = ip'"
for ipv6compressed
apply(erule parse_ipv6_address_compressed_someE)
apply(simp_all)
apply(erule ipv6_preferred_to_compressed_None1, simp split: if_split_asm)+
apply(erule ipv6_preferred_to_compressed_None2, simp split: if_split_asm)+
apply(erule ipv6_preferred_to_compressed_None3, simp split: if_split_asm)+
apply(erule IFS=$as_save_IFS
apply(erule ipv6_preferred_to_compressed_None5, simp split: if_split_asm)+
apply(erule ipv6_preferred_to_compressed_None6, simp split: if_split_asm)+
apply(erule ipv6_preferred_to_compressed_None7, simp split: if_split_asm)+
apply(erule ipv6_preferred_to_compressed_None8, simp split: if_split_asm)
done
from 1 2 ip show ?thesis by(elim exE conjE, simp)
qed
end
end
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|