Theory NetworkCore
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2017 Université Paris-Sud, France * 2015-2017 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection‹Packets and Networks› theory NetworkCore imports Main begin text‹ In networks based e.g. on TCP/IP, a message from A to B is encapsulated in \emph{packets}, which contain the content of the message and routing information. The routing information mainly contains its source and its destination address. In the case of stateless packet filters, a firewall bases its decision upon this routing information and, in the stateful case, on the content. Thus, we model a packet as a four-tuple of the mentioned elements, together with an id field. › text‹The ID is an integer:› type_synonym id = int text‹ To enable different representations of addresses (e.g. IPv4 and IPv6, with or without ports), we model them as an unconstrained type class and directly provide several instances: › class adr type_synonym 'α src = "'α" type_synonym 'α dest = "'α" instance int ::adr .. instance nat ::adr .. instance "fun" :: (adr,adr) adr .. instance prod :: (adr,adr) adr .. text‹ The content is also specified with an unconstrained generic type: › type_synonym 'β content = "'β" text ‹ For applications where the concrete representation of the content field does not matter (usually the case for stateless packet filters), we provide a default type which can be used in those cases: › datatype DummyContent = data text‹Finally, a packet is:› type_synonym ('α,'β) packet = "id × 'α src × 'α dest × 'β content" text‹ Protocols (e.g. http) are not modelled explicitly. In the case of stateless packet filters, they are only visible by the destination port of a packet, which are modelled as part of the address. Additionally, stateful firewalls often determine the protocol by the content of a packet. › definition src :: "('α::adr,'β) packet ⇒ 'α" where "src = fst o snd " text‹ Port numbers (which are part of an address) are also modelled in a generic way. The integers and the naturals are typical representations of port numbers. › class port instance int ::port .. instance nat :: port .. instance "fun" :: (port,port) port .. instance "prod" :: (port,port) port .. text‹ A packet therefore has two parameters, the first being the address, the second the content. For the sake of simplicity, we do not allow to have a different address representation format for the source and the destination of a packet. To access the different parts of a packet directly, we define a couple of projectors: › definition id :: "('α::adr,'β) packet ⇒ id" where "id = fst" definition dest :: "('α::adr,'β) packet ⇒ 'α dest" where "dest = fst o snd o snd" definition content :: "('α::adr,'β) packet ⇒ 'β content" where "content = snd o snd o snd" datatype protocol = tcp | udp lemma either: "⟦a ≠ tcp;a ≠ udp⟧ ⟹ False" by (case_tac "a",simp_all) lemma either2[simp]: "(a ≠ tcp) = (a = udp)" by (case_tac "a",simp_all) lemma either3[simp]: "(a ≠ udp) = (a = tcp)" by (case_tac "a",simp_all) text‹ The following two constants give the source and destination port number of a packet. Address representations using port numbers need to provide a definition for these types. › consts src_port :: "('α::adr,'β) packet ⇒ 'γ::port" consts dest_port :: "('α::adr,'β) packet ⇒ 'γ::port" consts src_protocol :: "('α::adr,'β) packet ⇒ protocol" consts dest_protocol :: "('α::adr,'β) packet ⇒ protocol" text‹A subnetwork (or simply a network) is a set of sets of addresses.› type_synonym 'α net = "'α set set" text‹The relation {in\_subnet} (‹⊏›) checks if an address is in a specific network.› definition in_subnet :: "'α::adr ⇒ 'α net ⇒ bool" (infixl "⊏" 100) where "in_subnet a S = (∃ s ∈ S. a ∈ s)" text‹The following lemmas will be useful later.› lemma in_subnet: "(a, e) ⊏ {{(x1,y). P x1 y}} = P a e" by (simp add: in_subnet_def) lemma src_in_subnet: "src(q,(a,e),r,t) ⊏ {{(x1,y). P x1 y}} = P a e" by (simp add: in_subnet_def in_subnet src_def) lemma dest_in_subnet: "dest (q,r,((a),e),t) ⊏ {{(x1,y). P x1 y}} = P a e" by (simp add: in_subnet_def in_subnet dest_def) text‹ Address models should provide a definition for the following constant, returning a network consisting of the input address only. › consts subnet_of :: "'α::adr ⇒ 'α net" lemmas packet_defs = in_subnet_def id_def content_def src_def dest_def end
Theory DatatypeAddress
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Datatype Addresses› theory DatatypeAddress imports NetworkCore begin text‹ A theory describing a network consisting of three subnetworks. Hosts within a network are not distinguished. › datatype DatatypeAddress = dmz_adr | intranet_adr | internet_adr definition dmz::"DatatypeAddress net" where "dmz = {{dmz_adr}}" definition intranet::"DatatypeAddress net" where "intranet = {{intranet_adr}}" definition internet::"DatatypeAddress net" where "internet = {{internet_adr}}" end
Theory DatatypePort
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Datatype Addresses with Ports› theory DatatypePort imports NetworkCore begin text‹ A theory describing a network consisting of three subnetworks, including port numbers modelled as Integers. Hosts within a network are not distinguished. › datatype DatatypeAddress = dmz_adr | intranet_adr | internet_adr type_synonym port = int type_synonym DatatypePort = "(DatatypeAddress × port)" instance DatatypeAddress :: adr .. definition dmz::"DatatypePort net" where "dmz = {{(a,b). a = dmz_adr}}" definition intranet::"DatatypePort net" where "intranet = {{(a,b). a = intranet_adr}}" definition internet::"DatatypePort net" where "internet = {{(a,b). a = internet_adr}}" overloading src_port_datatype ≡ "src_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "src_port_datatype (x::(DatatypePort,'β) packet) ≡ (snd o fst o snd) x" end overloading dest_port_datatype ≡ "dest_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "dest_port_datatype (x::(DatatypePort,'β) packet) ≡(snd o fst o snd o snd) x" end overloading subnet_of_datatype ≡ "subnet_of :: 'α::adr ⇒ 'α net" begin definition "subnet_of_datatype (x::DatatypePort) ≡ {{(a,b::int). a = fst x}}" end lemma src_port : "src_port ((a,x,d,e)::(DatatypePort,'β) packet) = snd x" by (simp add: src_port_datatype_def in_subnet) lemma dest_port : "dest_port ((a,d,x,e)::(DatatypePort,'β) packet) = snd x" by (simp add: dest_port_datatype_def in_subnet) lemmas DatatypePortLemmas = src_port dest_port src_port_datatype_def dest_port_datatype_def end
Theory IntegerAddress
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Integer Addresses› theory IntegerAddress imports NetworkCore begin text‹A theory where addresses are modelled as Integers.› type_synonym adr⇩i = "int" end
Theory IntegerPort
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection‹Integer Addresses with Ports› theory IntegerPort imports NetworkCore begin text‹ A theory describing addresses which are modelled as a pair of Integers - the first being the host address, the second the port number. › type_synonym address = int type_synonym port = int type_synonym adr⇩i⇩p = "address × port" overloading src_port_int ≡ "src_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "src_port_int (x::(adr⇩i⇩p,'β) packet) ≡ (snd o fst o snd) x" end overloading dest_port_int ≡ "dest_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "dest_port_int (x::(adr⇩i⇩p,'β) packet) ≡ (snd o fst o snd o snd) x" end overloading subnet_of_int ≡ "subnet_of :: 'α::adr ⇒ 'α net" begin definition "subnet_of_int (x::(adr⇩i⇩p)) ≡ {{(a,b::int). a = fst x}}" end lemma src_port: "src_port (a,x::adr⇩i⇩p,d,e) = snd x" by (simp add: src_port_int_def in_subnet) lemma dest_port: "dest_port (a,d,x::adr⇩i⇩p,e) = snd x" by (simp add: dest_port_int_def in_subnet) lemmas adr⇩i⇩pLemmas = src_port dest_port src_port_int_def dest_port_int_def end
Theory IntegerPort_TCPUDP
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Integer Addresses with Ports and Protocols› theory IntegerPort_TCPUDP imports NetworkCore begin text‹A theory describing addresses which are modelled as a pair of Integers - the first being the host address, the second the port number.› type_synonym address = int type_synonym port = int type_synonym adr⇩i⇩p⇩p = "address × port × protocol" instance protocol :: adr .. overloading src_port_int_TCPUDP ≡ "src_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "src_port_int_TCPUDP (x::(adr⇩i⇩p⇩p,'β) packet) ≡ (fst o snd o fst o snd) x" end overloading dest_port_int_TCPUDP ≡ "dest_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "dest_port_int_TCPUDP (x::(adr⇩i⇩p⇩p,'β) packet) ≡ (fst o snd o fst o snd o snd) x" end overloading subnet_of_int_TCPUDP ≡ "subnet_of :: 'α::adr ⇒ 'α net" begin definition "subnet_of_int_TCPUDP (x::(adr⇩i⇩p⇩p)) ≡ {{(a,b,c). a = fst x}}::adr⇩i⇩p⇩p net" end overloading src_protocol_int_TCPUDP ≡ "src_protocol :: ('α::adr,'β) packet ⇒ protocol" begin definition "src_protocol_int_TCPUDP (x::(adr⇩i⇩p⇩p,'β) packet) ≡ (snd o snd o fst o snd) x" end overloading dest_protocol_int_TCPUDP ≡ "dest_protocol :: ('α::adr,'β) packet ⇒ protocol" begin definition "dest_protocol_int_TCPUDP (x::(adr⇩i⇩p⇩p,'β) packet) ≡ (snd o snd o fst o snd o snd) x" end lemma src_port: "src_port (a,x::adr⇩i⇩p⇩p,d,e) = fst (snd x)" by (simp add: src_port_int_TCPUDP_def in_subnet) lemma dest_port: "dest_port (a,d,x::adr⇩i⇩p⇩p,e) = fst (snd x)" by (simp add: dest_port_int_TCPUDP_def in_subnet) text ‹Common test constraints:› definition port_positive :: "(adr⇩i⇩p⇩p,'b) packet ⇒ bool" where "port_positive x = (dest_port x > (0::port))" definition fix_values :: "(adr⇩i⇩p⇩p,DummyContent) packet ⇒ bool" where "fix_values x = (src_port x = (1::port) ∧ src_protocol x = udp ∧ content x = data ∧ id x = 1)" lemmas adr⇩i⇩p⇩pLemmas = src_port dest_port src_port_int_TCPUDP_def dest_port_int_TCPUDP_def src_protocol_int_TCPUDP_def dest_protocol_int_TCPUDP_def subnet_of_int_TCPUDP_def lemmas adr⇩i⇩p⇩pTestConstraints = port_positive_def fix_values_def end
Theory IPv4
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Formalizing IPv4 Addresses› theory IPv4 imports NetworkCore begin text‹ A theory describing IPv4 addresses with ports. The host address is a four-tuple of Integers, the port number is a single Integer. › type_synonym ipv4_ip = "(int × int × int × int)" type_synonym port = "int" type_synonym ipv4 = "(ipv4_ip × port)" overloading src_port_ipv4 ≡ "src_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "src_port_ipv4 (x::(ipv4,'β) packet) ≡ (snd o fst o snd) x" end overloading dest_port_ipv4 ≡ "dest_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "dest_port_ipv4 (x::(ipv4,'β) packet) ≡ (snd o fst o snd o snd) x" end overloading subnet_of_ipv4 ≡ "subnet_of :: 'α::adr ⇒ 'α net" begin definition "subnet_of_ipv4 (x::ipv4) ≡ {{(a,b::int). a = fst x}}" end definition subnet_of_ip :: "ipv4_ip ⇒ ipv4 net" where "subnet_of_ip ip = {{(a,b). (a = ip)}}" lemma src_port: "src_port (a,(x::ipv4),d,e) = snd x" by (simp add: src_port_ipv4_def in_subnet) lemma dest_port: "dest_port (a,d,(x::ipv4),e) = snd x" by (simp add: dest_port_ipv4_def in_subnet) lemmas IPv4Lemmas = src_port dest_port src_port_ipv4_def dest_port_ipv4_def end
Theory IPv4_TCPUDP
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹IPv4 with Ports and Protocols› theory IPv4_TCPUDP imports IPv4 begin type_synonym ipv4_TCPUDP = "(ipv4_ip × port × protocol)" instance protocol :: adr .. overloading src_port_ipv4_TCPUDP ≡ "src_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "src_port_ipv4_TCPUDP (x::(ipv4_TCPUDP,'β) packet) ≡ (fst o snd o fst o snd) x" end overloading dest_port_ipv4_TCPUDP ≡ "dest_port :: ('α::adr,'β) packet ⇒ 'γ::port" begin definition "dest_port_ipv4_TCPUDP (x::(ipv4_TCPUDP,'β) packet) ≡ (fst o snd o fst o snd o snd) x" end overloading subnet_of_ipv4_TCPUDP ≡ "subnet_of :: 'α::adr ⇒ 'α net" begin definition "subnet_of_ipv4_TCPUDP (x::ipv4_TCPUDP) ≡ {{(a,b). a = fst x}}::(ipv4_TCPUDP net)" end overloading dest_protocol_ipv4_TCPUDP ≡ "dest_protocol :: ('α::adr,'β) packet ⇒ protocol" begin definition "dest_protocol_ipv4_TCPUDP (x::(ipv4_TCPUDP,'β) packet) ≡ (snd o snd o fst o snd o snd) x" end definition subnet_of_ip :: "ipv4_ip ⇒ ipv4_TCPUDP net" where "subnet_of_ip ip = {{(a,b). (a = ip)}}" lemma src_port: "src_port (a,(x::ipv4_TCPUDP),d,e) = fst (snd x)" by (simp add: src_port_ipv4_TCPUDP_def in_subnet) lemma dest_port: "dest_port (a,d,(x::ipv4_TCPUDP),e) = fst (snd x)" by (simp add: dest_port_ipv4_TCPUDP_def in_subnet) lemmas Ipv4_TCPUDPLemmas = src_port dest_port src_port_ipv4_TCPUDP_def dest_port_ipv4_TCPUDP_def dest_protocol_ipv4_TCPUDP_def subnet_of_ipv4_TCPUDP_def end
Theory NetworkModels
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) section‹Network Models› theory NetworkModels imports DatatypeAddress DatatypePort IntegerAddress IntegerPort IntegerPort_TCPUDP IPv4 IPv4_TCPUDP begin text‹ One can think of many different possible address representations. In this distribution, we include seven different variants: \begin{itemize} \item DatatypeAddress: Three explicitly named addresses, which build up a network consisting of three disjunct subnetworks. I.e. there are no overlaps and there is no way to distinguish between individual hosts within a network. \item DatatypePort: An address is a pair, with the first element being the same as above, and the second being a port number modelled as an Integer\footnote{For technical reasons, we always use Integers instead of Naturals. As a consequence, the (test) specifications have to be adjusted to eliminate negative numbers.}. \item adr\_i: An address in an Integer. \item adr\_ip: An address is a pair of an Integer and a port (which is again an Integer). \item adr\_ipp: An address is a triple consisting of two Integers modelling the IP address and the port number, and the specification of the network protocol \item IPv4: An address is a pair. The first element is a four-tuple of Integers, modelling an IPv4 address, the second element is an Integer denoting the port number. \item IPv4\_TCPUDP: The same as above, but including additionally the specification of the network protocol. \end{itemize} The theories of each pf the networks are relatively small. It suffices to provide the required types, a couple of lemmas, and - if required - a definition for the source and destination ports of a packet. › end
Theory PolicyCore
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Policy Core› theory PolicyCore imports NetworkCore UPF.UPF begin text‹A policy is seen as a partial mapping from packet to packet out.› type_synonym ('α, 'β) FWPolicy = "('α, 'β) packet ↦ unit" text‹ When combining several rules, the firewall is supposed to apply the first matching one. In our setting this means the first rule which maps the packet in question to ‹Some (packet out)›. This is exactly what happens when using the map-add operator (‹rule1 ++ rule2›). The only difference is that the rules must be given in reverse order. › text‹ The constant ‹p_accept› is ‹True› iff the policy accepts the packet. › definition p_accept :: "('α, 'β) packet ⇒ ('α, 'β) FWPolicy ⇒ bool" where "p_accept p pol = (pol p = ⌊allow ()⌋)" end
Theory PolicyCombinators
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2017 Université Paris-Sud, France * 2015-2017 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Policy Combinators› theory PolicyCombinators imports PolicyCore begin text‹In order to ease the specification of a concrete policy, we define some combinators. Using these combinators, the specification of a policy gets very easy, and can be done similarly as in tools like IPTables.› definition allow_all_from :: "'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from src_net = {pa. src pa ⊏ src_net} ◃ A⇩U " definition deny_all_from :: "'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from src_net = {pa. src pa ⊏ src_net} ◃D⇩U " definition allow_all_to :: "'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_to dest_net = {pa. dest pa ⊏ dest_net} ◃ A⇩U" definition deny_all_to :: "'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_all_to dest_net = {pa. dest pa ⊏ dest_net} ◃D⇩U " definition allow_all_from_to :: "'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_to src_net dest_net = {pa. src pa ⊏ src_net ∧ dest pa ⊏ dest_net} ◃ A⇩U " definition deny_all_from_to :: "'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_to src_net dest_net = {pa. src pa ⊏ src_net ∧ dest pa ⊏ dest_net} ◃ D⇩U" text‹All these combinators and the default rules are put into one single lemma called ‹PolicyCombinators› to facilitate proving over policies.› lemmas PolicyCombinators = allow_all_from_def deny_all_from_def allow_all_to_def deny_all_to_def allow_all_from_to_def deny_all_from_to_def UPFDefs end
Theory PortCombinators
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Policy Combinators with Ports› theory PortCombinators imports PolicyCombinators begin text‹ This theory defines policy combinators for those network models which have ports. They are provided in addition to the the ones defined in the PolicyCombinators theory. This theory requires from the network models a definition for the two following constants: \begin{itemize} \item $src\_port :: ('\alpha,'\beta) packet \Rightarrow ('\gamma::port)$ \item $dest\_port :: ('\alpha,'\beta) packet \Rightarrow ('\gamma::port)$ \end{itemize} › definition allow_all_from_port :: "'α::adr net ⇒ ('γ::port) ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port src_net s_port = {pa. src_port pa = s_port} ◃ allow_all_from src_net" definition deny_all_from_port :: "'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port src_net s_port = {pa. src_port pa = s_port} ◃ deny_all_from src_net " definition allow_all_to_port :: "'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_to_port dest_net d_port = {pa. dest_port pa = d_port} ◃ allow_all_to dest_net" definition deny_all_to_port :: "'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_to_port dest_net d_port = {pa. dest_port pa = d_port} ◃ deny_all_to dest_net" definition allow_all_from_port_to:: "'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_to src_net s_port dest_net = {pa. src_port pa = s_port} ◃ allow_all_from_to src_net dest_net" definition deny_all_from_port_to::"'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port_to src_net s_port dest_net = {pa. src_port pa = s_port} ◃ deny_all_from_to src_net dest_net " definition allow_all_from_port_to_port::"'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_to_port src_net s_port dest_net d_port = {pa. dest_port pa = d_port} ◃ allow_all_from_port_to src_net s_port dest_net" definition deny_all_from_port_to_port :: "'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port_to_port src_net s_port dest_net d_port = {pa. dest_port pa = d_port} ◃ deny_all_from_port_to src_net s_port dest_net" definition allow_all_from_to_port :: "'α::adr net ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_to_port src_net dest_net d_port = {pa. dest_port pa = d_port} ◃ allow_all_from_to src_net dest_net" definition deny_all_from_to_port :: "'α::adr net ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_to_port src_net dest_net d_port = {pa. dest_port pa = d_port} ◃ deny_all_from_to src_net dest_net" definition allow_from_port_to :: "'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_port_to port src_net dest_net = {pa. src_port pa = port} ◃ allow_all_from_to src_net dest_net" definition deny_from_port_to :: "'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_port_to port src_net dest_net = {pa. src_port pa = port} ◃ deny_all_from_to src_net dest_net" definition allow_from_to_port :: "'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_to_port port src_net dest_net = {pa. dest_port pa = port} ◃ allow_all_from_to src_net dest_net" definition deny_from_to_port :: "'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_to_port port src_net dest_net = {pa. dest_port pa = port} ◃ deny_all_from_to src_net dest_net" definition allow_from_ports_to :: "'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_ports_to ports src_net dest_net = {pa. src_port pa ∈ ports} ◃ allow_all_from_to src_net dest_net" definition allow_from_to_ports :: "'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_to_ports ports src_net dest_net = {pa. dest_port pa ∈ ports} ◃ allow_all_from_to src_net dest_net" definition deny_from_ports_to :: "'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_ports_to ports src_net dest_net = {pa. src_port pa ∈ ports} ◃ deny_all_from_to src_net dest_net" definition deny_from_to_ports :: "'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_to_ports ports src_net dest_net = {pa. dest_port pa ∈ ports} ◃ deny_all_from_to src_net dest_net" definition allow_all_from_port_tos:: "'α::adr net ⇒ ('γ::port) set ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_tos src_net s_port dest_net = {pa. dest_port pa ∈ s_port} ◃ allow_all_from_to src_net dest_net" text‹ As before, we put all the rules into one lemma called PortCombinators to ease writing later. › lemmas PortCombinatorsCore = allow_all_from_port_def deny_all_from_port_def allow_all_to_port_def deny_all_to_port_def allow_all_from_to_port_def deny_all_from_to_port_def allow_from_ports_to_def allow_from_to_ports_def deny_from_ports_to_def deny_from_to_ports_def allow_all_from_port_to_def deny_all_from_port_to_def allow_from_port_to_def allow_from_to_port_def deny_from_to_port_def deny_from_port_to_def allow_all_from_port_tos_def lemmas PortCombinators = PortCombinatorsCore PolicyCombinators end
Theory ProtocolPortCombinators
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Policy Combinators with Ports and Protocols› theory ProtocolPortCombinators imports PortCombinators begin text‹ This theory defines policy combinators for those network models which have ports. They are provided in addition to the the ones defined in the PolicyCombinators theory. This theory requires from the network models a definition for the two following constants: \begin{itemize} \item $src\_port :: ('\alpha,'\beta) packet \Rightarrow ('\gamma::port)$ \item $dest\_port :: ('\alpha,'\beta) packet \Rightarrow ('\gamma::port)$ \end{itemize} › definition allow_all_from_port_prot :: "protocol ⇒ 'α::adr net ⇒ ('γ::port) ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_prot p src_net s_port = {pa. dest_protocol pa = p} ◃ allow_all_from_port src_net s_port" definition deny_all_from_port_prot :: "protocol =>'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port_prot p src_net s_port = {pa. dest_protocol pa = p} ◃ deny_all_from_port src_net s_port" definition allow_all_to_port_prot :: "protocol =>'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_to_port_prot p dest_net d_port = {pa. dest_protocol pa = p} ◃ allow_all_to_port dest_net d_port" definition deny_all_to_port_prot :: "protocol =>'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_to_port_prot p dest_net d_port = {pa. dest_protocol pa = p} ◃ deny_all_to_port dest_net d_port" definition allow_all_from_port_to_prot:: "protocol =>'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_to_prot p src_net s_port dest_net = {pa. dest_protocol pa = p} ◃ allow_all_from_port_to src_net s_port dest_net" definition deny_all_from_port_to_prot::"protocol ⇒ 'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port_to_prot p src_net s_port dest_net = {pa. dest_protocol pa = p} ◃ deny_all_from_port_to src_net s_port dest_net" definition allow_all_from_port_to_port_prot::"protocol ⇒ 'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_port_to_port_prot p src_net s_port dest_net d_port = {pa. dest_protocol pa = p} ◃ allow_all_from_port_to_port src_net s_port dest_net d_port " definition deny_all_from_port_to_port_prot :: "protocol =>'α::adr net ⇒ 'γ::port ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_port_to_port_prot p src_net s_port dest_net d_port = {pa. dest_protocol pa = p} ◃ deny_all_from_port_to_port src_net s_port dest_net d_port" definition allow_all_from_to_port_prot :: "protocol =>'α::adr net ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "allow_all_from_to_port_prot p src_net dest_net d_port = {pa. dest_protocol pa = p} ◃ allow_all_from_to_port src_net dest_net d_port " definition deny_all_from_to_port_prot :: "protocol =>'α::adr net ⇒ 'α::adr net ⇒ 'γ::port ⇒ (('α,'β) packet ↦ unit)" where "deny_all_from_to_port_prot p src_net dest_net d_port = {pa. dest_protocol pa = p} ◃ deny_all_from_to_port src_net dest_net d_port" definition allow_from_port_to_prot :: "protocol =>'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_port_to_prot p port src_net dest_net = {pa. dest_protocol pa = p} ◃ allow_from_port_to port src_net dest_net" definition deny_from_port_to_prot :: "protocol =>'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_port_to_prot p port src_net dest_net = {pa. dest_protocol pa = p} ◃ deny_from_port_to port src_net dest_net" definition allow_from_to_port_prot :: "protocol =>'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_to_port_prot p port src_net dest_net = {pa. dest_protocol pa = p} ◃ allow_from_to_port port src_net dest_net" definition deny_from_to_port_prot :: "protocol =>'γ::port ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_to_port_prot p port src_net dest_net = {pa. dest_protocol pa = p} ◃ deny_from_to_port port src_net dest_net" definition allow_from_ports_to_prot :: "protocol =>'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_ports_to_prot p ports src_net dest_net = {pa. dest_protocol pa = p} ◃ allow_from_ports_to ports src_net dest_net" definition allow_from_to_ports_prot :: "protocol =>'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "allow_from_to_ports_prot p ports src_net dest_net = {pa. dest_protocol pa = p} ◃ allow_from_to_ports ports src_net dest_net" definition deny_from_ports_to_prot :: "protocol =>'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_ports_to_prot p ports src_net dest_net = {pa. dest_protocol pa = p} ◃ deny_from_ports_to ports src_net dest_net" definition deny_from_to_ports_prot :: "protocol =>'γ::port set ⇒ 'α::adr net ⇒ 'α::adr net ⇒ (('α,'β) packet ↦ unit)" where "deny_from_to_ports_prot p ports src_net dest_net = {pa. dest_protocol pa = p} ◃ deny_from_to_ports ports src_net dest_net" text‹As before, we put all the rules into one lemma to ease writing later.› lemmas ProtocolCombinatorsCore = allow_all_from_port_prot_def deny_all_from_port_prot_def allow_all_to_port_prot_def deny_all_to_port_prot_def allow_all_from_to_port_prot_def deny_all_from_to_port_prot_def allow_from_ports_to_prot_def allow_from_to_ports_prot_def deny_from_ports_to_prot_def deny_from_to_ports_prot_def allow_all_from_port_to_prot_def deny_all_from_port_to_prot_def allow_from_port_to_prot_def allow_from_to_port_prot_def deny_from_to_port_prot_def deny_from_port_to_prot_def lemmas ProtocolCombinators = PortCombinators.PortCombinators ProtocolCombinatorsCore end
Theory Ports
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Ports› theory Ports imports Main begin text‹ This theory can be used if we want to specify the port numbers by names denoting their default Integer values. If you want to use them, please add ‹Ports› to the simplifier. › definition http::int where "http = 80" lemma http1: "x ≠ 80 ⟹ x ≠ http" by (simp add: http_def) lemma http2: "x ≠ 80 ⟹ http ≠ x" by (simp add: http_def) definition smtp::int where "smtp = 25" lemma smtp1: "x ≠ 25 ⟹ x ≠ smtp" by (simp add: smtp_def) lemma smtp2: "x ≠ 25 ⟹ smtp ≠ x" by (simp add: smtp_def) definition ftp::int where "ftp = 21" lemma ftp1: "x ≠ 21 ⟹ x ≠ ftp" by (simp add: ftp_def) lemma ftp2: "x ≠ 21 ⟹ ftp ≠ x" by (simp add: ftp_def) text‹And so on for all desired port numbers.› lemmas Ports = http1 http2 ftp1 ftp2 smtp1 smtp2 end
Theory PacketFilter
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) section ‹Network Policies: Packet Filter› theory PacketFilter imports NetworkModels ProtocolPortCombinators Ports begin end
Theory NAT
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection‹Network Address Translation› theory NAT imports "../PacketFilter/PacketFilter" begin definition src2pool :: "'α set ⇒ ('α::adr,'β) packet ⇒ ('α,'β) packet set" where "src2pool t = (λ p. ({(i,s,d,da). (i = id p ∧ s ∈ t ∧ d = dest p ∧ da = content p)}))" definition src2poolAP where "src2poolAP t = A⇩f (src2pool t)" definition srcNat2pool :: "'α set ⇒ 'α set ⇒ ('α::adr,'β) packet ↦ ('α,'β) packet set" where "srcNat2pool srcs transl = {x. src x ∈ srcs} ◃ (src2poolAP transl)" definition src2poolPort :: "int set ⇒ (adr⇩i⇩p,'β) packet ⇒ (adr⇩i⇩p,'β) packet set" where "src2poolPort t = (λ p. ({(i,(s1,s2),(d1,d2),da). (i = id p ∧ s1 ∈ t ∧ s2 = (snd (src p)) ∧ d1 = (fst (dest p)) ∧ d2 = snd (dest p) ∧ da = content p)}))" definition src2poolPort_Protocol :: "int set ⇒ (adr⇩i⇩p⇩p,'β) packet ⇒ (adr⇩i⇩p⇩p,'β) packet set" where "src2poolPort_Protocol t = (λ p. ({(i,(s1,s2,s3),(d1,d2,d3), da). (i = id p ∧ s1 ∈ t ∧ s2 = (fst (snd (src p))) ∧ s3 = snd (snd (src p)) ∧ (d1,d2,d3) = dest p ∧ da = content p)}))" definition srcNat2pool_IntPort :: "address set ⇒ address set ⇒ (adr⇩i⇩p,'β) packet ↦ (adr⇩i⇩p,'β) packet set" where "srcNat2pool_IntPort srcs transl = {x. fst (src x) ∈ srcs} ◃ (A⇩f (src2poolPort transl))" definition srcNat2pool_IntProtocolPort :: "int set ⇒ int set ⇒ (adr⇩i⇩p⇩p,'β) packet ↦ (adr⇩i⇩p⇩p,'β) packet set" where "srcNat2pool_IntProtocolPort srcs transl = {x. (fst ( (src x))) ∈ srcs} ◃ (A⇩f (src2poolPort_Protocol transl))" definition srcPat2poolPort_t :: "int set ⇒ (adr⇩i⇩p,'β) packet ⇒ (adr⇩i⇩p,'β) packet set" where "srcPat2poolPort_t t = (λ p. ({(i,(s1,s2),(d1,d2),da). (i = id p ∧ s1 ∈ t ∧ d1 = (fst (dest p)) ∧ d2 = snd (dest p)∧ da = content p)}))" definition srcPat2poolPort_Protocol_t :: "int set ⇒ (adr⇩i⇩p⇩p,'β) packet ⇒ (adr⇩i⇩p⇩p,'β) packet set" where "srcPat2poolPort_Protocol_t t = (λ p. ({(i,(s1,s2,s3),(d1,d2,d3),da). (i = id p ∧ s1 ∈ t ∧ s3 = src_protocol p ∧ (d1,d2,d3) = dest p ∧ da = content p)}))" definition srcPat2pool_IntPort :: "int set ⇒ int set ⇒ (adr⇩i⇩p,'β) packet ↦ (adr⇩i⇩p,'β) packet set" where "srcPat2pool_IntPort srcs transl = {x. (fst (src x)) ∈ srcs} ◃ (A⇩f (srcPat2poolPort_t transl))" definition srcPat2pool_IntProtocol :: "int set ⇒ int set ⇒ (adr⇩i⇩p⇩p,'β) packet ↦ (adr⇩i⇩p⇩p,'β) packet set" where "srcPat2pool_IntProtocol srcs transl = {x. (fst (src x)) ∈ srcs} ◃ (A⇩f (srcPat2poolPort_Protocol_t transl))" text‹ The following lemmas are used for achieving a normalized output format of packages after applying NAT. This is used, e.g., by our firewall execution tool. › lemma datasimp: "{(i, (s1, s2, s3), aba). ∀a aa b ba. aba = ((a, aa, b), ba) ⟶ i = i1 ∧ s1 = i101 ∧ s3 = iudp ∧ a = i110 ∧ aa = X606X3 ∧ b = X607X4 ∧ ba = data} = {(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i101 ∧ s3 = iudp ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = X606X3 ∧ b = X607X4 ∧ ba = data) aba}" by auto lemma datasimp2: "{(i, (s1, s2, s3), aba). ∀a aa b ba. aba = ((a, aa, b), ba) ⟶ i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = i1 ∧ a = i110 ∧ aa = i4 ∧ b = iudp ∧ ba = data} = {(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = i1 ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = i4 ∧ b = iudp ∧ ba = data) aba}" by auto lemma datasimp3: "{(i, (s1, s2, s3), aba). ∀ a aa b ba. aba = ((a, aa, b), ba) ⟶ i = i1 ∧ i115 < s1 ∧ s1 < i124 ∧ s3 = iudp ∧ s2 = ii1 ∧ a = i110 ∧ aa = i3 ∧ b = itcp ∧ ba = data} = {(i, (s1, s2, s3), aba). i = i1 ∧ i115 < s1 ∧ s1 < i124 ∧ s3 = iudp ∧ s2 = ii1 ∧ (λ ((a,aa,b),ba). a = i110 & aa = i3 & b = itcp & ba = data) aba}" by auto lemma datasimp4: "{(i, (s1, s2, s3), aba). ∀a aa b ba. aba = ((a, aa, b), ba) ⟶ i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = ii1 ∧ a = i110 ∧ aa = i7 ∧ b = itcp ∧ ba = data} = {(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = ii1 ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = i7 ∧ b = itcp ∧ ba = data) aba}" by auto lemma datasimp5: " {(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i101 ∧ s3 = iudp ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = X606X3 ∧ b = X607X4 ∧ ba = data) aba} = {(i, (s1, s2, s3), (a,aa,b),ba). i = i1 ∧ s1 = i101 ∧ s3 = iudp ∧ a = i110 ∧ aa = X606X3 ∧ b = X607X4 ∧ ba = data}" by auto lemma datasimp6: "{(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = i1 ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = i4 ∧ b = iudp ∧ ba = data) aba} = {(i, (s1, s2, s3), (a,aa,b),ba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = i1 ∧ a = i110 ∧ aa = i4 ∧ b = iudp ∧ ba = data}" by auto lemma datasimp7: "{(i, (s1, s2, s3), aba). i = i1 ∧ i115 < s1 ∧ s1 < i124 ∧ s3 = iudp ∧ s2 = ii1 ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = i3 ∧ b = itcp ∧ ba = data) aba} = {(i, (s1, s2, s3), (a,aa,b),ba). i = i1 ∧ i115 < s1 ∧ s1 < i124 ∧ s3 = iudp ∧ s2 = ii1 ∧ a = i110 ∧ aa = i3 ∧ b = itcp ∧ ba = data}" by auto lemma datasimp8: "{(i, (s1, s2, s3), aba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = ii1 ∧ (λ ((a,aa,b),ba). a = i110 ∧ aa = i7 ∧ b = itcp ∧ ba = data) aba} = {(i, (s1, s2, s3), (a,aa,b),ba). i = i1 ∧ s1 = i132 ∧ s3 = iudp ∧ s2 = ii1 ∧ a = i110 ∧ aa = i7 ∧ b = itcp ∧ ba = data}" by auto lemmas datasimps = datasimp datasimp2 datasimp3 datasimp4 datasimp5 datasimp6 datasimp7 datasimp8 lemmas NATLemmas = src2pool_def src2poolPort_def src2poolPort_Protocol_def src2poolAP_def srcNat2pool_def srcNat2pool_IntProtocolPort_def srcNat2pool_IntPort_def srcPat2poolPort_t_def srcPat2poolPort_Protocol_t_def srcPat2pool_IntPort_def srcPat2pool_IntProtocol_def end
Theory FWNormalisationCore
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2016 Université Paris-Sud, France * 2015-2016 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection ‹Policy Normalisation: Core Definitions› theory FWNormalisationCore imports "../PacketFilter/PacketFilter" begin text‹ This theory contains all the definitions used for policy normalisation as described in~\cite{brucker.ea:icst:2010,brucker.ea:formal-fw-testing:2014}. The normalisation procedure transforms policies into semantically equivalent ones which are ``easier'' to test. It is organized into nine phases. We impose the following two restrictions on the input policies: \begin{itemize} \item Each policy must contain a $\mathtt{DenyAll}$ rule. If this restriction were to be lifted, the $\mathtt{insertDenies}$ phase would have to be adjusted accordingly. \item For each pair of networks $n_1$ and $n_2$, the networks are either disjoint or equal. If this restriction were to be lifted, we would need some additional phases before the start of the normalisation procedure presented below. This rule would split single rules into several by splitting up the networks such that they are all pairwise disjoint or equal. Such a transformation is clearly semantics-preserving and the condition would hold after these phases. \end{itemize} As a result, the procedure generates a list of policies, in which: \begin{itemize} \item each element of the list contains a policy which completely specifies the blocking behavior between two networks, and \item there are no shadowed rules. \end{itemize} This result is desirable since the test case generation for rules between networks $A$ and $B$ is independent of the rules that specify the behavior for traffic flowing between networks $C$ and $D$. Thus, the different segments of the policy can be processed individually. The normalization procedure does not aim to minimize the number of rules. While it does remove unnecessary ones, it also adds new ones, enabling a policy to be split into several independent parts. › text‹ Policy transformations are functions that map policies to policies. We decided to represent policy transformations as \emph{syntactic rules}; this choice paves the way for expressing the entire normalisation process inside HOL by functions manipulating abstract policy syntax. › subsubsection‹Basics› text‹We define a very simple policy language:› datatype ('α,'β) Combinators = DenyAll | DenyAllFromTo 'α 'α | AllowPortFromTo 'α 'α 'β | Conc "(('α,'β) Combinators)" "(('α,'β) Combinators)" (infixr "⊕" 80) text‹ And define the semantic interpretation of it. For technical reasons, we fix here the type to policies over IntegerPort addresses. However, we could easily provide definitions for other address types as well, using a generic constants for the type definition and a primitive recursive definition for each desired address model. › subsubsection‹Auxiliary definitions and functions.› text‹ This section defines several functions which are useful later for the combinators, invariants, and proofs. › fun srcNet where "srcNet (DenyAllFromTo x y) = x" |"srcNet (AllowPortFromTo x y p) = x" |"srcNet DenyAll = undefined" |"srcNet (v ⊕ va) = undefined" fun destNet where "destNet (DenyAllFromTo x y) = y" |"destNet (AllowPortFromTo x y p) = y" |"destNet DenyAll = undefined" |"destNet (v ⊕ va) = undefined" fun srcnets where "srcnets DenyAll = [] " |"srcnets (DenyAllFromTo x y) = [x] " |"srcnets (AllowPortFromTo x y p) = [x] " |"(srcnets (x ⊕ y)) = (srcnets x)@(srcnets y)" fun destnets where "destnets DenyAll = [] " |"destnets (DenyAllFromTo x y) = [y] " |"destnets (AllowPortFromTo x y p) = [y] " |"(destnets (x ⊕ y)) = (destnets x)@(destnets y)" fun (sequential) net_list_aux where "net_list_aux [] = []" |"net_list_aux (DenyAll#xs) = net_list_aux xs" |"net_list_aux ((DenyAllFromTo x y)#xs) = x#y#(net_list_aux xs)" |"net_list_aux ((AllowPortFromTo x y p)#xs) = x#y#(net_list_aux xs)" |"net_list_aux ((x⊕y)#xs) = (net_list_aux [x])@(net_list_aux [y])@(net_list_aux xs)" fun net_list where "net_list p = remdups (net_list_aux p)" definition bothNets where "bothNets x = (zip (srcnets x) (destnets x))" fun (sequential) normBothNets where "normBothNets ((a,b)#xs) = (if ((b,a) ∈ set xs) ∨ (a,b) ∈ set (xs) then (normBothNets xs) else (a,b)#(normBothNets xs))" |"normBothNets x = x" fun makeSets where "makeSets ((a,b)#xs) = ({a,b}#(makeSets xs))" |"makeSets [] = []" fun bothNet where "bothNet DenyAll = {}" |"bothNet (DenyAllFromTo a b) = {a,b}" |"bothNet (AllowPortFromTo a b p) = {a,b}" |"bothNet (v ⊕ va) = undefined " text‹ $Nets\_List$ provides from a list of rules a list where the entries are the appearing sets of source and destination network of each rule. › definition Nets_List where "Nets_List x = makeSets (normBothNets (bothNets x))" fun (sequential) first_srcNet where "first_srcNet (x⊕y) = first_srcNet x" | "first_srcNet x = srcNet x" fun (sequential) first_destNet where "first_destNet (x⊕y) = first_destNet x" | "first_destNet x = destNet x" fun (sequential) first_bothNet where "first_bothNet (x⊕y) = first_bothNet x" |"first_bothNet x = bothNet x" fun (sequential) in_list where "in_list DenyAll l = True" |"in_list x l = (bothNet x ∈ set l)" fun all_in_list where "all_in_list [] l = True" |"all_in_list (x#xs) l = (in_list x l ∧ all_in_list xs l)" fun (sequential) member where "member a (x⊕xs) = ((member a x) ∨ (member a xs))" |"member a x = (a = x)" fun sdnets where "sdnets DenyAll = {}" | "sdnets (DenyAllFromTo a b) = {(a,b)}" | "sdnets (AllowPortFromTo a b c) = {(a,b)}" | "sdnets (a ⊕ b) = sdnets a ∪ sdnets b" definition packet_Nets where "packet_Nets x a b = ((src x ⊏ a ∧ dest x ⊏ b) ∨ (src x ⊏ b ∧ dest x ⊏ a))" definition subnetsOfAdr where "subnetsOfAdr a = {x. a ⊏ x}" definition fst_set where "fst_set s = {a. ∃ b. (a,b) ∈ s}" definition snd_set where "snd_set s = {a. ∃ b. (b,a) ∈ s}" fun memberP where "memberP r (x#xs) = (member r x ∨ memberP r xs)" |"memberP r [] = False" fun firstList where "firstList (x#xs) = (first_bothNet x)" |"firstList [] = {}" subsubsection‹Invariants› text‹If there is a DenyAll, it is at the first position› fun wellformed_policy1:: "(('α, 'β) Combinators) list ⇒ bool" where "wellformed_policy1 [] = True" | "wellformed_policy1 (x#xs) = (DenyAll ∉ (set xs))" text‹There is a DenyAll at the first position› fun wellformed_policy1_strong:: "(('α, 'β) Combinators) list ⇒ bool" where "wellformed_policy1_strong [] = False" | "wellformed_policy1_strong (x#xs) = (x=DenyAll ∧ (DenyAll ∉ (set xs)))" text‹All two networks are either disjoint or equal.› definition netsDistinct where "netsDistinct a b = (¬ (∃ x. x ⊏ a ∧ x ⊏ b))" definition twoNetsDistinct where "twoNetsDistinct a b c d = (netsDistinct a c ∨ netsDistinct b d)" definition allNetsDistinct where "allNetsDistinct p = (∀ a b. (a ≠ b ∧ a ∈ set (net_list p) ∧ b ∈ set (net_list p)) ⟶ netsDistinct a b)" definition disjSD_2 where "disjSD_2 x y = (∀ a b c d. ((a,b)∈sdnets x ∧ (c,d) ∈sdnets y ⟶ (twoNetsDistinct a b c d ∧ twoNetsDistinct a b d c)))" text‹The policy is given as a list of single rules.› fun singleCombinators where "singleCombinators [] = True" |"singleCombinators ((x⊕y)#xs) = False" |"singleCombinators (x#xs) = singleCombinators xs" definition onlyTwoNets where "onlyTwoNets x = ((∃ a b. (sdnets x = {(a,b)})) ∨ (∃ a b. sdnets x = {(a,b),(b,a)}))" text‹Each entry of the list contains rules between two networks only.› fun OnlyTwoNets where "OnlyTwoNets (DenyAll#xs) = OnlyTwoNets xs" |"OnlyTwoNets (x#xs) = (onlyTwoNets x ∧ OnlyTwoNets xs)" |"OnlyTwoNets [] = True" fun noDenyAll where "noDenyAll (x#xs) = ((¬ member DenyAll x) ∧ noDenyAll xs)" |"noDenyAll [] = True" fun noDenyAll1 where "noDenyAll1 (DenyAll#xs) = noDenyAll xs" | "noDenyAll1 xs = noDenyAll xs" fun separated where "separated (x#xs) = ((∀ s. s ∈ set xs ⟶ disjSD_2 x s) ∧ separated xs)" | "separated [] = True" fun NetsCollected where "NetsCollected (x#xs) = (((first_bothNet x ≠ firstList xs) ⟶ (∀a∈set xs. first_bothNet x ≠ first_bothNet a)) ∧ NetsCollected (xs))" | "NetsCollected [] = True" fun NetsCollected2 where "NetsCollected2 (x#xs) = (xs = [] ∨ (first_bothNet x ≠ firstList xs ∧ NetsCollected2 xs))" |"NetsCollected2 [] = True" subsubsection‹Transformations› text ‹ The following two functions transform a policy into a list of single rules and vice-versa (by staying on the combinator level). › fun policy2list::"('α, 'β) Combinators ⇒ (('α, 'β) Combinators) list" where "policy2list (x ⊕ y) = (concat [(policy2list x),(policy2list y)])" |"policy2list x = [x]" fun list2FWpolicy::"(('α, 'β) Combinators) list ⇒ (('α, 'β) Combinators)" where "list2FWpolicy [] = undefined " |"list2FWpolicy (x#[]) = x" |"list2FWpolicy (x#y) = x ⊕ (list2FWpolicy y)" text‹Remove all the rules appearing before a DenyAll. There are two alternative versions.› fun removeShadowRules1 where "removeShadowRules1 (x#xs) = (if (DenyAll ∈ set xs) then ((removeShadowRules1 xs)) else x#xs)" | "removeShadowRules1 [] = []" fun removeShadowRules1_alternative_rev where "removeShadowRules1_alternative_rev [] = []" | "removeShadowRules1_alternative_rev (DenyAll#xs) = [DenyAll]" | "removeShadowRules1_alternative_rev [x] = [x]" | "removeShadowRules1_alternative_rev (x#xs)= x#(removeShadowRules1_alternative_rev xs)" definition removeShadowRules1_alternative where "removeShadowRules1_alternative p = rev (removeShadowRules1_alternative_rev (rev p))" text‹ Remove all the rules which allow a port, but are shadowed by a deny between these subnets. › fun removeShadowRules2:: "(('α, 'β) Combinators) list ⇒ (('α, 'β) Combinators) list" where "(removeShadowRules2 ((AllowPortFromTo x y p)#z)) = (if (((DenyAllFromTo x y) ∈ set z)) then ((removeShadowRules2 z)) else (((AllowPortFromTo x y p)#(removeShadowRules2 z))))" | "removeShadowRules2 (x#y) = x#(removeShadowRules2 y)" | "removeShadowRules2 [] = []" text‹ Sorting a policies: We first need to define an ordering on rules. This ordering depends on the $Nets\_List$ of a policy. › fun smaller :: "('α, 'β) Combinators ⇒ ('α, 'β) Combinators ⇒ (('α) set) list ⇒ bool" where "smaller DenyAll x l = True" | "smaller x DenyAll l = False" | "smaller x y l = ((x = y) ∨ (if (bothNet x) = (bothNet y) then (case y of (DenyAllFromTo a b) ⇒ (x = DenyAllFromTo b a) | _ ⇒ True) else (position (bothNet x) l <= position (bothNet y) l)))" text‹We provide two different sorting algorithms: Quick Sort (qsort) and Insertion Sort (sort)› fun qsort where "qsort [] l = []" | "qsort (x#xs) l = (qsort [y←xs. ¬ (smaller x y l)] l) @ [x] @ (qsort [y←xs. smaller x y l] l)" lemma qsort_permutes: "set (qsort xs l) = set xs" apply (induct "xs" "l" rule: qsort.induct) by (auto) lemma set_qsort [simp]: "set (qsort xs l) = set xs" by (simp add: qsort_permutes) fun insort where "insort a [] l = [a]" | "insort a (x#xs) l = (if (smaller a x l) then a#x#xs else x#(insort a xs l))" fun sort where "sort [] l = []" | "sort (x#xs) l = insort x (sort xs l) l" fun sorted where "sorted [] l = True" | "sorted [x] l = True" | "sorted (x#y#zs) l = (smaller x y l ∧ sorted (y#zs) l)" fun separate where "separate (DenyAll#x) = DenyAll#(separate x)" | "separate (x#y#z) = (if (first_bothNet x = first_bothNet y) then (separate ((x⊕y)#z)) else (x#(separate(y#z))))" |"separate x = x" text ‹ Insert the DenyAllFromTo rules, such that traffic between two networks can be tested individually. › fun insertDenies where "insertDenies (x#xs) = (case x of DenyAll ⇒ (DenyAll#(insertDenies xs)) | _ ⇒ (DenyAllFromTo (first_srcNet x) (first_destNet x) ⊕ (DenyAllFromTo (first_destNet x) (first_srcNet x)) ⊕ x)# (insertDenies xs))" | "insertDenies [] = []" text‹ Remove duplicate rules. This is especially necessary as insertDenies might have inserted duplicate rules. The second function is supposed to work on a list of policies. Only rules which are duplicated within the same policy are removed. › fun removeDuplicates where "removeDuplicates (x⊕xs) = (if member x xs then (removeDuplicates xs) else x⊕(removeDuplicates xs))" | "removeDuplicates x = x" fun removeAllDuplicates where "removeAllDuplicates (x#xs) = ((removeDuplicates (x))#(removeAllDuplicates xs))" |"removeAllDuplicates x = x" text ‹Insert a DenyAll at the beginning of a policy.› fun insertDeny where "insertDeny (DenyAll#xs) = DenyAll#xs" |"insertDeny xs = DenyAll#xs" definition "sort' p l = sort l p" definition "qsort' p l = qsort l p" declare dom_eq_empty_conv [simp del] fun list2policyR::"(('α, 'β) Combinators) list ⇒ (('α, 'β) Combinators)" where "list2policyR (x#[]) = x" |"list2policyR (x#y) = (list2policyR y) ⊕ x" |"list2policyR [] = undefined " text‹ We provide the definitions for two address representations. › subsubsection‹IntPort› fun C :: "(adr⇩i⇩p net, port) Combinators ⇒ (adr⇩i⇩p,DummyContent) packet ↦ unit" where " C DenyAll = deny_all" |"C (DenyAllFromTo x y) = deny_all_from_to x y" |"C (AllowPortFromTo x y p) = allow_from_to_port p x y" |"C (x ⊕ y) = C x ++ C y" fun CRotate :: "(adr⇩i⇩p net, port) Combinators ⇒ (adr⇩i⇩p,DummyContent) packet ↦ unit" where " CRotate DenyAll = C DenyAll" |"CRotate (DenyAllFromTo x y) = C (DenyAllFromTo x y)" |"CRotate (AllowPortFromTo x y p) = C (AllowPortFromTo x y p)" |"CRotate (x ⊕ y) = ((CRotate y) ++ ((CRotate x)))" fun rotatePolicy where "rotatePolicy DenyAll = DenyAll" | "rotatePolicy (DenyAllFromTo a b) = DenyAllFromTo a b" | "rotatePolicy (AllowPortFromTo a b p) = AllowPortFromTo a b p" | "rotatePolicy (a⊕b) = (rotatePolicy b) ⊕ (rotatePolicy a)" lemma check: "rev (policy2list (rotatePolicy p)) = policy2list p" apply (induct "p") by (simp_all) text‹ All rules appearing at the left of a DenyAllFromTo, have disjunct domains from it (except DenyAll). › fun (sequential) wellformed_policy2 where "wellformed_policy2 [] = True" | "wellformed_policy2 (DenyAll#xs) = wellformed_policy2 xs" | "wellformed_policy2 (x#xs) = ((∀ c a b. c = DenyAllFromTo a b ∧ c ∈ set xs ⟶ Map.dom (C x) ∩ Map.dom (C c) = {}) ∧ wellformed_policy2 xs)" text‹ An allow rule is disjunct with all rules appearing at the right of it. This invariant is not necessary as it is a consequence from others, but facilitates some proofs. › fun (sequential) wellformed_policy3::"((adr⇩i⇩p net,port) Combinators) list ⇒ bool" where "wellformed_policy3 [] = True" | "wellformed_policy3 ((AllowPortFromTo a b p)#xs) = ((∀ r. r ∈ set xs ⟶ dom (C r) ∩ dom (C (AllowPortFromTo a b p)) = {}) ∧ wellformed_policy3 xs)" | "wellformed_policy3 (x#xs) = wellformed_policy3 xs" definition "normalize' p = (removeAllDuplicates o insertDenies o separate o (sort' (Nets_List p)) o removeShadowRules2 o remdups o (rm_MT_rules C) o insertDeny o removeShadowRules1 o policy2list) p" definition "normalizeQ' p = (removeAllDuplicates o insertDenies o separate o (qsort' (Nets_List p)) o removeShadowRules2 o remdups o (rm_MT_rules C) o insertDeny o removeShadowRules1 o policy2list) p" definition normalize :: "(adr⇩i⇩p net, port) Combinators ⇒ (adr⇩i⇩p net, port) Combinators list" where "normalize p = (removeAllDuplicates (insertDenies (separate (sort (removeShadowRules2 (remdups ((rm_MT_rules C) (insertDeny (removeShadowRules1 (policy2list p)))))) ((Nets_List p))))))" definition "normalize_manual_order p l = removeAllDuplicates (insertDenies (separate (sort (removeShadowRules2 (remdups ((rm_MT_rules C) (insertDeny (removeShadowRules1 (policy2list p)))))) ((l)))))" definition normalizeQ :: "(adr⇩i⇩p net, port) Combinators ⇒ (adr⇩i⇩p net, port) Combinators list" where "normalizeQ p = (removeAllDuplicates (insertDenies (separate (qsort (removeShadowRules2 (remdups ((rm_MT_rules C) (insertDeny (removeShadowRules1 (policy2list p)))))) ((Nets_List p))))))" definition "normalize_manual_orderQ p l = removeAllDuplicates (insertDenies (separate (qsort (removeShadowRules2 (remdups ((rm_MT_rules C) (insertDeny (removeShadowRules1 (policy2list p)))))) ((l)))))" text‹ Of course, normalize is equal to normalize', the latter looks nicer though. › lemma "normalize = normalize'" by (rule ext, simp add: normalize_def normalize'_def sort'_def) declare C.simps [simp del] subsubsection‹TCP\_UDP\_IntegerPort› fun Cp :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p,DummyContent) packet ↦ unit" where " Cp DenyAll = deny_all" |"Cp (DenyAllFromTo x y) = deny_all_from_to x y" |"Cp (AllowPortFromTo x y p) = allow_from_to_port_prot (fst p) (snd p) x y" |"Cp (x ⊕ y) = Cp x ++ Cp y" fun Dp :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p,DummyContent) packet ↦ unit" where " Dp DenyAll = Cp DenyAll" |"Dp (DenyAllFromTo x y) = Cp (DenyAllFromTo x y)" |"Dp (AllowPortFromTo x y p) = Cp (AllowPortFromTo x y p)" |"Dp (x ⊕ y) = Cp (y ⊕ x)" text‹ All rules appearing at the left of a DenyAllFromTo, have disjunct domains from it (except DenyAll). › fun (sequential) wellformed_policy2Pr where "wellformed_policy2Pr [] = True" | "wellformed_policy2Pr (DenyAll#xs) = wellformed_policy2Pr xs" | "wellformed_policy2Pr (x#xs) = ((∀ c a b. c = DenyAllFromTo a b ∧ c ∈ set xs ⟶ Map.dom (Cp x) ∩ Map.dom (Cp c) = {}) ∧ wellformed_policy2Pr xs)" text‹ An allow rule is disjunct with all rules appearing at the right of it. This invariant is not necessary as it is a consequence from others, but facilitates some proofs. › fun (sequential) wellformed_policy3Pr::"((adr⇩i⇩p⇩p net, protocol × port) Combinators) list ⇒ bool" where "wellformed_policy3Pr [] = True" | "wellformed_policy3Pr ((AllowPortFromTo a b p)#xs) = ((∀ r. r ∈ set xs ⟶ dom (Cp r) ∩ dom (Cp (AllowPortFromTo a b p)) = {}) ∧ wellformed_policy3Pr xs)" | "wellformed_policy3Pr (x#xs) = wellformed_policy3Pr xs" definition normalizePr' :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p net, protocol × port) Combinators list" where "normalizePr' p = (removeAllDuplicates o insertDenies o separate o (sort' (Nets_List p)) o removeShadowRules2 o remdups o (rm_MT_rules Cp) o insertDeny o removeShadowRules1 o policy2list) p" definition normalizePr :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p net, protocol × port) Combinators list" where "normalizePr p = (removeAllDuplicates (insertDenies (separate (sort (removeShadowRules2 (remdups ((rm_MT_rules Cp) (insertDeny (removeShadowRules1 (policy2list p)))))) ((Nets_List p))))))" definition "normalize_manual_orderPr p l = removeAllDuplicates (insertDenies (separate (sort (removeShadowRules2 (remdups ((rm_MT_rules Cp) (insertDeny (removeShadowRules1 (policy2list p)))))) ((l)))))" definition normalizePrQ' :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p net, protocol × port) Combinators list" where "normalizePrQ' p = (removeAllDuplicates o insertDenies o separate o (qsort' (Nets_List p)) o removeShadowRules2 o remdups o (rm_MT_rules Cp) o insertDeny o removeShadowRules1 o policy2list) p" definition normalizePrQ :: "(adr⇩i⇩p⇩p net, protocol × port) Combinators ⇒ (adr⇩i⇩p⇩p net, protocol × port) Combinators list" where "normalizePrQ p = (removeAllDuplicates (insertDenies (separate (qsort (removeShadowRules2 (remdups ((rm_MT_rules Cp) (insertDeny (removeShadowRules1 (policy2list p)))))) ((Nets_List p))))))" definition "normalize_manual_orderPrQ p l = removeAllDuplicates (insertDenies (separate (qsort (removeShadowRules2 (remdups ((rm_MT_rules Cp) (insertDeny (removeShadowRules1 (policy2list p)))))) ((l)))))" text‹ Of course, normalize is equal to normalize', the latter looks nicer though. › lemma "normalizePr = normalizePr'" by (rule ext, simp add: normalizePr_def normalizePr'_def sort'_def) text‹ The following definition helps in creating the test specification for the individual parts of a normalized policy. › definition makeFUTPr where "makeFUTPr FUT p x n = (packet_Nets x (fst (normBothNets (bothNets p)!n)) (snd(normBothNets (bothNets p)!n)) ⟶ FUT x = Cp ((normalizePr p)!Suc n) x)" declare Cp.simps [simp del] lemmas PLemmas = C.simps Cp.simps dom_def PolicyCombinators.PolicyCombinators PortCombinators.PortCombinatorsCore aux ProtocolPortCombinators.ProtocolCombinatorsCore src_def dest_def in_subnet_def adr⇩i⇩p⇩pLemmas adr⇩i⇩p⇩pLemmas lemma aux: "⟦x ≠ a; y≠b; (x ≠ y ∧ x ≠ b) ∨ (a ≠ b ∧ a ≠ y)⟧ ⟹ {x,a} ≠ {y,b}" by (auto) lemma aux2: "{a,b} = {b,a}" by auto end
Theory NormalisationGenericProofs
(***************************************************************************** * Copyright (c) 2005-2010 ETH Zurich, Switzerland * 2008-2015 Achim D. Brucker, Germany * 2009-2017 Université Paris-Sud, France * 2015-2017 The University of Sheffield, UK * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************) subsection‹Normalisation Proofs (Generic)› theory NormalisationGenericProofs imports FWNormalisationCore begin text ‹ This theory contains the generic proofs of the normalisation procedure, i.e. those which are independent from the concrete semantical interpretation function. › lemma domNMT: "dom X ≠ {} ⟹ X ≠ ∅" by auto lemma denyNMT: "deny_all ≠ ∅" apply (rule domNMT) by (simp add: deny_all_def dom_def) lemma wellformed_policy1_charn[rule_format]: "wellformed_policy1 p ⟶ DenyAll ∈ set p ⟶ (∃ p'. p = DenyAll # p' ∧ DenyAll ∉ set p')" by(induct "p",simp_all) lemma singleCombinatorsConc: "singleCombinators (x#xs) ⟹ singleCombinators xs" by (case_tac x,simp_all) lemma aux0_0: "singleCombinators x ⟹ ¬ (∃ a b. (a⊕b) ∈ set x)" apply (induct "x", simp_all) subgoal for a b by (case_tac "a",simp_all) done lemma aux0_4: "(a ∈ set x ∨ a ∈ set y) = (a ∈ set (x@y))" by auto lemma aux0_1: "⟦singleCombinators xs; singleCombinators [x]⟧ ⟹ singleCombinators (x#xs)" by (case_tac "x",simp_all) lemma aux0_6: "⟦singleCombinators xs; ¬ (∃ a b. x = a ⊕ b)⟧ ⟹ singleCombinators(x#xs)" apply (rule aux0_1,simp_all) apply (case_tac "x",simp_all) done lemma aux0_5: " ¬ (∃ a b. (a⊕b) ∈ set x) ⟹ singleCombinators x" apply (induct "x") apply simp_all by (metis aux0_6) lemma ANDConc[rule_format]: "allNetsDistinct (a#p) ⟶ allNetsDistinct (p)" apply (simp add: allNetsDistinct_def) apply (case_tac "a") by simp_all lemma aux6: "twoNetsDistinct a1 a2 a b ⟹ dom (deny_all_from_to a1 a2) ∩ dom (deny_all_from_to a b) = {}" by (auto simp: twoNetsDistinct_def netsDistinct_def src_def dest_def in_subnet_def PolicyCombinators.PolicyCombinators dom_def) lemma aux5[rule_format]: "(DenyAllFromTo a b) ∈ set p ⟶ a ∈ set (net_list p)" by (rule net_list_aux.induct,simp_all) lemma aux5a[rule_format]: "(DenyAllFromTo b a) ∈ set p ⟶ a ∈ set (net_list p)" by (rule net_list_aux.induct,simp_all) lemma aux5c[rule_format]: "(AllowPortFromTo a b po) ∈ set p ⟶ a ∈ set (net_list p)" by (rule net_list_aux.induct,simp_all) lemma aux5d[rule_format]: "(AllowPortFromTo b a po) ∈ set p ⟶ a ∈ set (net_list p)" by (rule net_list_aux.induct,simp_all) lemma aux10[rule_format]: "a ∈ set (net_list p) ⟶ a ∈ set (net_list_aux p)" by simp lemma srcInNetListaux[simp]: "⟦x ∈ set p; singleCombinators[x]; x ≠ DenyAll⟧ ⟹ srcNet x ∈ set (net_list_aux p)" apply (induct "p") apply simp_all subgoal for a p apply (case_tac "x = a", simp_all) apply (case_tac a, simp_all) apply (case_tac a, simp_all) done done lemma destInNetListaux[simp]: "⟦x ∈ set p; singleCombinators[x]; x ≠ DenyAll⟧ ⟹ destNet x ∈ set (net_list_aux p)" apply (induct p) apply simp_all subgoal for a p apply (case_tac "x = a", simp_all) apply (case_tac "a", simp_all) apply (case_tac "a", simp_all) done done lemma tND1: "⟦allNetsDistinct p; x ∈ set p; y ∈ set p; a = srcNet x; b = destNet x; c = srcNet y; d = destNet y; a ≠ c; singleCombinators[x]; x ≠ DenyAll; singleCombinators[y]; y ≠ DenyAll⟧ ⟹ twoNetsDistinct a b c d" by (simp add: allNetsDistinct_def twoNetsDistinct_def) lemma tND2: "⟦allNetsDistinct p; x ∈ set p; y ∈ set p; a = srcNet x; b = destNet x; c = srcNet y; d = destNet y; b ≠ d; singleCombinators[x]; x ≠ DenyAll; singleCombinators[y]; y ≠ DenyAll⟧ ⟹ twoNetsDistinct a b c d" by (simp add: allNetsDistinct_def twoNetsDistinct_def) lemma tND: "⟦allNetsDistinct p; x ∈ set p; y ∈ set p; a = srcNet x; b = destNet x; c = srcNet y; d = destNet y; a ≠ c ∨ b ≠ d; singleCombinators[x]; x ≠ DenyAll; singleCombinators[y]; y ≠ DenyAll⟧ ⟹ twoNetsDistinct a b c d" apply (case_tac "a ≠ c", simp_all) apply (erule_tac x = x and y =y in tND1, simp_all) apply (erule_tac x = x and y =y in tND2, simp_all) done lemma aux7: "⟦DenyAllFromTo a b ∈ set p; allNetsDistinct ((DenyAllFromTo c d)#p); a≠ c∨ b≠ d⟧ ⟹ twoNetsDistinct a b c d" apply (erule_tac x = "DenyAllFromTo a b" and y = "DenyAllFromTo c d" in tND) by simp_all lemma aux7a: "⟦DenyAllFromTo a b ∈ set p; allNetsDistinct ((AllowPortFromTo c d po)#p); a ≠ c∨ b ≠ d⟧ ⟹ twoNetsDistinct a b c d" apply (erule_tac x = "DenyAllFromTo a b" and y = "AllowPortFromTo c d po" in tND) by simp_all lemma nDComm: assumes ab: "netsDistinct a b" shows ba: "netsDistinct b a" apply (insert ab) by (auto simp: netsDistinct_def in_subnet_def) lemma tNDComm: assumes abcd: "twoNetsDistinct a b c d" shows "twoNetsDistinct c d a b" apply (insert abcd) by (metis twoNetsDistinct_def nDComm) lemma aux[rule_format]: "a ∈ set (removeShadowRules2 p) ⟶ a ∈ set p" apply (case_tac a) by (rule removeShadowRules2.induct, simp_all)+ lemma aux12: "⟦a ∈ x; b ∉ x⟧ ⟹ a ≠ b" by auto lemma ND0aux1[rule_format]: "DenyAllFromTo x y ∈ set b ⟹ x ∈ set (net_list_aux b)" by (metis aux5 net_list.simps set_remdups) lemma ND0aux2[rule_format]: "DenyAllFromTo x y ∈ set b ⟹ y ∈ set (net_list_aux b)" by (metis aux5a net_list.simps set_remdups) lemma ND0aux3[rule_format]: "AllowPortFromTo x y p ∈ set b ⟹ x ∈ set (net_list_aux b)" by (metis aux5c net_list.simps set_remdups) lemma ND0aux4[rule_format]: "AllowPortFromTo x y p ∈ set b ⟹ y ∈ set (net_list_aux b)" by (metis aux5d net_list.simps set_remdups) lemma aNDSubsetaux[rule_format]: "singleCombinators a ⟶ set a ⊆ set b ⟶ set (net_list_aux a) ⊆ set (net_list_aux b)" apply (induct a) apply simp_all apply clarify apply (drule mp, erule singleCombinatorsConc) subgoal for a a' x apply (case_tac "a") apply (simp_all add: contra_subsetD) apply (metis contra_subsetD) apply (metis ND0aux1 ND0aux2 contra_subsetD) apply (metis ND0aux3 ND0aux4 contra_subsetD) done done lemma aNDSetsEqaux[rule_format]: "singleCombinators a ⟶ singleCombinators b ⟶ set a = set b ⟶ set (net_list_aux a) = set (net_list_aux b)" apply (rule impI)+ apply (rule equalityI) apply (rule aNDSubsetaux, simp_all)+ done lemma aNDSubset: "⟦singleCombinators a;set a ⊆ set b; allNetsDistinct b⟧ ⟹ allNetsDistinct a" apply (simp add: allNetsDistinct_def) apply (rule allI)+ apply (rule impI)+ subgoal for x y apply (drule_tac x = "x" in spec, drule_tac x = "y" in spec) using aNDSubsetaux by blast done lemma aNDSetsEq: "⟦singleCombinators a; singleCombinators b; set a = set b; allNetsDistinct b⟧ ⟹ allNetsDistinct a" apply (simp add: allNetsDistinct_def) apply (rule allI)+ apply (rule impI)+ subgoal for x y apply (drule_tac x = "x" in spec, drule_tac x = "y" in spec) using aNDSetsEqaux by auto done lemma SCConca: "⟦singleCombinators p; singleCombinators [a]⟧ ⟹ singleCombinators (a#p)" by(metis aux0_1) lemma aux3[simp]: "⟦singleCombinators p; singleCombinators [a]; allNetsDistinct (a#p)⟧ ⟹ allNetsDistinct (a#a#p)" by (metis aNDSetsEq aux0_1 insert_absorb2 list.set(2)) lemma wp1_aux1a[rule_format]: "xs ≠ [] ⟶ wellformed_policy1_strong (xs @ [x]) ⟶ wellformed_policy1_strong xs" by (induct xs,simp_all) lemma wp1alternative_RS1[rule_format]: "DenyAll ∈ set p ⟶ wellformed_policy1_strong (removeShadowRules1 p)" by (induct p,simp_all) lemma wellformed_eq: "DenyAll ∈ set p ⟶ ((wellformed_policy1 p) = (wellformed_policy1_strong p))" by (induct p,simp_all) lemma set_insort: "set(insort x xs l) = insert x (set xs)" by (induct xs) auto lemma set_sort[simp]: "set(sort xs l) = set xs" by (induct xs) (simp_all add:set_insort) lemma set_sortQ: "set(qsort xs l) = set xs" by simp lemma aux79[rule_format]: "y ∈ set (insort x a l) ⟶ y ≠ x ⟶ y ∈ set a" apply (induct a) by auto lemma aux80: "⟦y ∉ set p; y ≠ x⟧ ⟹ y ∉ set (insort x (sort p l) l)" apply (metis aux79 set_sort) done lemma WP1Conca: "DenyAll ∉ set p ⟹ wellformed_policy1 (a#p)" by (case_tac a,simp_all) lemma saux[simp]: "(insort DenyAll p l) = DenyAll#p" by (induct_tac p,simp_all) lemma saux3[rule_format]: "DenyAllFromTo a b ∈ set list ⟶ DenyAllFromTo c d ∉ set list ⟶ (a ≠ c) ∨ (b ≠ d)" by blast lemma waux2[rule_format]: " (DenyAll ∉ set xs) ⟶ wellformed_policy1 xs" by (induct_tac xs,simp_all) lemma waux3[rule_format]: "⟦x ≠ a; x ∉ set p⟧ ⟹ x ∉ set (insort a p l)" by (metis aux79) lemma wellformed1_sorted_aux[rule_format]: "wellformed_policy1 (x#p) ⟹ wellformed_policy1 (insort x p l)" by (metis NormalisationGenericProofs.set_insort list.set(2) saux waux2 wellformed_eq wellformed_policy1_strong.simps(2)) lemma wellformed1_sorted_auxQ[rule_format]: "wellformed_policy1 (p) ⟹ wellformed_policy1 (qsort p l)" proof (induct p) case Nil show ?case by simp next case (Cons a S) then show ?case apply simp_all apply (cases a,simp_all) by (metis Combinators.simps append_Cons append_Nil qsort.simps(2) set_ConsD set_qsort waux2)+ qed lemma SR1Subset: "set (removeShadowRules1 p) ⊆ set p" apply (induct_tac p, simp_all) subgoal for x xs apply (case_tac "x", simp_all) apply(auto) done done lemma SCSubset[rule_format]: " singleCombinators b ⟶ set a ⊆ set b ⟶ singleCombinators a" proof (induct a) case Nil thus ?case by simp next case (Cons x xs) thus ?case by (meson aux0_0 aux0_5 subsetCE) qed lemma setInsert[simp]: "set list ⊆ insert a (set list)" by auto lemma SC_RS1[rule_format,simp]: "singleCombinators p ⟶ allNetsDistinct p ⟶ singleCombinators (removeShadowRules1 p)" apply (induct_tac p) apply simp_all using ANDConc singleCombinatorsConc by blast lemma RS2Set[rule_format]: "set (removeShadowRules2 p) ⊆ set p" apply(induct p, simp_all) subgoal for a as apply(case_tac a) by(auto) done lemma WP1: "a ∉ set list ⟹ a ∉ set (removeShadowRules2 list)" using RS2Set [of list] by blast lemma denyAllDom[simp]: "x ∈ dom (deny_all)" by (simp add: UPFDefs(24) domI) lemma lCdom2: "(list2FWpolicy (a @ (b @ c))) = (list2FWpolicy ((a@b)@c))" by auto lemma SCConcEnd: "singleCombinators (xs @ [xa]) ⟹ singleCombinators xs" apply (induct "xs", simp_all) subgoal for a as by (case_tac "a" , simp_all) done lemma list2FWpolicyconc[rule_format]: "a ≠ [] ⟶ (list2FWpolicy (xa # a)) = (xa) ⊕ (list2FWpolicy a)" by (induct a,simp_all) lemma wp1n_tl [rule_format]: "wellformed_policy1_strong p ⟶ p = (DenyAll#(tl p))" by (induct p, simp_all) lemma foo2: "a ∉ set ps ⟹ a ∉ set ss ⟹ set p = set s ⟹ p = (a#(ps)) ⟹ s = (a#ss) ⟹ set (ps) = set (ss)" by auto lemma SCnotConc[rule_format,simp]: "a⊕b ∈ set p ⟶ singleCombinators p ⟶False" apply (induct p, simp_all) subgoal for p ps by(case_tac p, simp_all) done lemma auxx8: "removeShadowRules1_alternative_rev [x] = [x]" by (case_tac "x", simp_all) lemma RS1End[rule_format]: "x ≠ DenyAll ⟶ removeShadowRules1 (xs @ [x]) = (removeShadowRules1 xs)@[x]" by (induct_tac xs, simp_all) lemma aux114: "x ≠ DenyAll ⟹ removeShadowRules1_alternative_rev (x#xs) = x#(removeShadowRules1_alternative_rev xs)" apply (induct_tac xs) apply (auto simp: auxx8) by (case_tac "x", simp_all) lemma aux115[rule_format]: "x ≠ DenyAll⟹removeShadowRules1_alternative (xs@[x]) = (removeShadowRules1_alternative xs)@[x]" apply (simp add: removeShadowRules1_alternative_def aux114) done lemma RS1_DA[simp]: "removeShadowRules1 (xs @ [DenyAll]) = [DenyAll]" by (induct_tac xs, simp_all) lemma rSR1_eq: "removeShadowRules1_alternative = removeShadowRules1" apply (rule ext) apply (simp add: removeShadowRules1_alternative_def) subgoal for x apply (rule_tac xs = x in rev_induct) apply simp_all subgoal for x xs apply (case_tac "x = DenyAll", simp_all) apply (metis RS1End aux114 rev.simps(2)) done done done lemma domInterMT[rule_format]: "⟦dom a ∩ dom b = {}; x ∈ dom a⟧ ⟹ x ∉ dom b" by auto lemma domComm: "dom a ∩ dom b = dom b ∩ dom a" by auto lemma r_not_DA_in_tl[rule_format]: "wellformed_policy1_strong p ⟶ a ∈ set p⟶ a ≠ DenyAll ⟶ a ∈ set (tl p)" by (induct p,simp_all) lemma wp1_aux1aa[rule_format]: "wellformed_policy1_strong p ⟶ DenyAll ∈ set p" by (induct p,simp_all) lemma mauxa: "(∃ r. a b = ⌊r⌋) = (a b ≠ ⊥)" by auto lemma l2p_aux[rule_format]: "list ≠ [] ⟶ list2FWpolicy (a # list) = a ⊕(list2FWpolicy list)" by (induct "list", simp_all) lemma l2p_aux2[rule_format]: "list = [] ⟹ list2FWpolicy (a # list) = a" by simp lemma aux7aa: assumes 1 : "AllowPortFromTo a b poo ∈ set p" and 2 : "allNetsDistinct ((AllowPortFromTo c d po) # p)" and 3 : "a ≠ c ∨ b ≠ d" shows "twoNetsDistinct a b c d" (is "?H") proof(cases "a ≠ c") print_cases case True assume *:"a ≠ c" show ?H by (meson "1" "2" True allNetsDistinct_def aux5c list.set_intros(1) list.set_intros(2) twoNetsDistinct_def) next case False assume *:"¬(a ≠ c)" show "twoNetsDistinct a b c d" by (meson "1" "2" "3" False allNetsDistinct_def aux5d list.set_intros(1) list.set_intros(2) twoNetsDistinct_def) qed lemma ANDConcEnd: "⟦ allNetsDistinct (xs @ [xa]); singleCombinators xs⟧ ⟹ allNetsDistinct xs" by (rule aNDSubset, auto) lemma WP1ConcEnd[rule_format]: "wellformed_policy1 (xs@[xa]) ⟶ wellformed_policy1 xs" by (induct xs, simp_all) lemma NDComm: "netsDistinct a b = netsDistinct b a" by (auto simp: netsDistinct_def in_subnet_def) lemma wellformed1_sorted[simp]: assumes wp1: "wellformed_policy1 p" shows "wellformed_policy1 (sort p l)" proof (cases p) case Nil thus ?thesis by simp next case (Cons x xs) thus ?thesis proof (cases "x = DenyAll") case True thus ?thesis using assms Cons by simp next case False thus ?thesis using assms by (metis Cons set_sort False waux2 wellformed_eq wellformed_policy1_strong.simps(2)) qed qed lemma wellformed1_sortedQ[simp]: assumes wp1: "wellformed_policy1 p" shows "wellformed_policy1 (qsort p l)" proof (cases p) case Nil thus ?thesis by simp next case (Cons x xs) thus ?thesis proof (cases "x = DenyAll") case True thus ?thesis using assms Cons by simp next case False thus ?thesis using assms by (metis Cons set_qsort False waux2 wellformed_eq wellformed_policy1_strong.simps(2)) qed qed lemma SC1[simp]: "singleCombinators p ⟹singleCombinators (removeShadowRules1 p)" by (erule SCSubset) (rule SR1Subset) lemma SC2[simp]: "singleCombinators p ⟹singleCombinators (removeShadowRules2 p)" by (erule SCSubset) (rule RS2Set) lemma SC3[simp]: "singleCombinators p ⟹ singleCombinators (sort p l)" by (erule SCSubset) simp lemma SC3Q[simp]: "singleCombinators p ⟹ singleCombinators (qsort p l)" by (erule SCSubset) simp lemma aND_RS1[simp]: "⟦singleCombinators p; allNetsDistinct p⟧ ⟹ allNetsDistinct (removeShadowRules1 p)" apply (rule aNDSubset) apply (erule SC_RS1, simp_all) apply (rule SR1Subset) done lemma aND_RS2[simp]: "⟦singleCombinators p; allNetsDistinct p⟧ ⟹ allNetsDistinct (removeShadowRules2 p)" apply (rule aNDSubset) apply (erule SC2, simp_all) apply (rule RS2Set) done lemma aND_sort[simp]: "⟦singleCombinators p; allNetsDistinct p⟧ ⟹ allNetsDistinct (sort p l)" apply (rule aNDSubset) by (erule SC3, simp_all) lemma aND_sortQ[simp]: "⟦singleCombinators p; allNetsDistinct p⟧ ⟹ allNetsDistinct (qsort p l)" apply (rule aNDSubset) by (erule SC3Q, simp_all) lemma inRS2[rule_format,simp]: "x ∉ set p ⟶ x ∉ set (removeShadowRules2 p)" apply (insert RS2Set [of p]) by blast lemma distinct_RS2[rule_format,simp]: "distinct p ⟶ distinct (removeShadowRules2 p)" apply (induct p) apply simp_all apply clarify subgoal for a p apply (case_tac "a") by auto done lemma setPaireq: " {x, y} = {a, b} ⟹ x = a ∧ y = b ∨ x = b ∧ y = a" by (metis doubleton_eq_iff) lemma position_positive[rule_format]: "a ∈ set l ⟶ position a l > 0" by (induct l, simp_all) lemma pos_noteq[rule_format]: "a ∈ set l ⟶ b ∈ set l ⟶ c ∈ set l ⟶ a ≠ b ⟶ position a l ≤ position b l ⟶ position b l ≤ position c l ⟶ a ≠ c" proof(induct l) case Nil show ?case by simp next case (Cons a R) show ?case by (metis (no_types, lifting) Cons.hyps One_nat_def Suc_le_mono le_antisym length_greater_0_conv list.size(3) nat.inject position.simps(2) position_positive set_ConsD) qed lemma setPair_noteq: "{a,b} ≠ {c,d} ⟹ ¬ ((a = c) ∧ (b = d))" by auto lemma setPair_noteq_allow: "{a,b} ≠ {c,d} ⟹ ¬ ((a = c) ∧ (b = d) ∧ P)" by auto lemma order_trans: "⟦in_list x l; in_list y l; in_list z l; singleCombinators [x]; singleCombinators [y]; singleCombinators [z]; smaller x y l; smaller y z l⟧ ⟹ smaller x z l" apply (case_tac x, simp_all) apply (case_tac z, simp_all) apply (case_tac y, simp_all) apply (case_tac y, simp_all) apply (rule conjI|rule impI)+ apply (simp add: setPaireq) apply (rule conjI|rule impI)+ apply (simp_all split: if_splits) apply metis+ apply auto[1] apply (simp add: setPaireq) apply (rule impI,case_tac y, simp_all) apply (simp_all split: if_splits, metis,simp_all add: setPair_noteq setPair_noteq_allow) apply (case_tac z, simp_all) apply (case_tac y, simp_all) apply (case_tac y, simp_all) apply (intro impI|rule conjI)+ apply (simp_all split: if_splits) apply (simp add: setPair_noteq) apply (erule pos_noteq, simp_all) apply auto[1] apply (rule conjI,simp add: setPair_noteq_allow) apply (erule pos_noteq, simp_all) apply auto[1] apply (rule impI,rule disjI2) apply (case_tac y, simp_all split: if_splits ) apply metis apply (simp_all add: setPair_noteq_allow) done lemma sortedConcStart[rule_format]: "sorted (a # aa # p) l ⟶ in_list a l ⟶ in_list aa l ⟶ all_in_list p l⟶ singleCombinators [a] ⟶ singleCombinators [aa] ⟶ singleCombinators p ⟶ sorted (a#p) l" apply (induct p) apply simp_all apply (rule impI)+ apply simp apply (rule_tac y = "aa" in order_trans) apply simp_all subgoal for p ps apply (case_tac "p", simp_all) done done lemma singleCombinatorsStart[simp]: "singleCombinators (x#xs) ⟹ singleCombinators [x]" by (case_tac x, simp_all) lemma sorted_is_smaller[rule_format]: "sorted (a # p) l ⟶ in_list a l ⟶ in_list b l ⟶ all_in_list p l ⟶ singleCombinators [a] ⟶ singleCombinators p ⟶ b ∈ set p ⟶ smaller a b l" apply (induct p) apply (auto intro: singleCombinatorsConc sortedConcStart) done lemma sortedConcEnd[rule_format]: "sorted (a # p) l ⟶ in_list a l ⟶ all_in_list p l ⟶ singleCombinators [a] ⟶ singleCombinators p ⟶ sorted p l" apply (induct p) apply (auto intro: singleCombinatorsConc sortedConcStart) done lemma in_set_in_list[rule_format]: "a ∈ set p ⟶ all_in_list p l⟶ in_list a l" by (induct p) auto lemma sorted_Consb[rule_format]: "all_in_list (x#xs) l ⟶ singleCombinators (x#xs) ⟶ (sorted xs l & (∀y∈set xs. smaller x y l)) ⟶ (sorted (x#xs) l) " apply(induct xs arbitrary: x) apply (auto simp: order_trans) done lemma sorted_Cons: "⟦all_in_list (x#xs) l; singleCombinators (x#xs)⟧ ⟹ (sorted xs l & (∀y∈set xs. smaller x y l)) = (sorted (x#xs) l)" apply auto apply (rule sorted_Consb, simp_all) apply (metis singleCombinatorsConc singleCombinatorsStart sortedConcEnd) apply (erule sorted_is_smaller) apply (auto intro: singleCombinatorsConc singleCombinatorsStart in_set_in_list) done lemma smaller_antisym: "⟦¬ smaller a b l; in_list a l; in_list b l; singleCombinators[a]; singleCombinators [b]⟧ ⟹ smaller b a l" apply (case_tac a) apply simp_all apply (case_tac b) apply simp_all apply (simp_all split: if_splits) apply (rule setPaireq) apply simp apply (case_tac b) apply simp_all apply (simp_all split: if_splits) done lemma set_insort_insert: "set (insort x xs l) ⊆ insert x (set xs)" by (induct xs) auto lemma all_in_listSubset[rule_format]: "all_in_list b l ⟶singleCombinators a ⟶ set a ⊆ set b ⟶ all_in_list a l" by (induct_tac a) (auto intro: in_set_in_list singleCombinatorsConc) lemma singleCombinators_insort: "⟦singleCombinators [x]; singleCombinators xs⟧ ⟹ singleCombinators (insort x xs l)" by (metis NormalisationGenericProofs.set_insort aux0_0 aux0_1 aux0_5 list.simps(15)) lemma all_in_list_insort: "⟦all_in_list xs l; singleCombinators (x#xs); in_list x l⟧ ⟹ all_in_list (insort x xs l) l" apply (rule_tac b = "x#xs" in all_in_listSubset) apply simp_all apply (metis singleCombinatorsConc singleCombinatorsStart singleCombinators_insort) apply (rule set_insort_insert) done lemma sorted_ConsA:"⟦all_in_list (x#xs) l; singleCombinators (x#xs)⟧ ⟹ (sorted (x#xs) l) = (sorted xs l & (∀y∈set xs. smaller x y l))" by (metis sorted_Cons) lemma is_in_insort: "y ∈ set xs ⟹ y ∈ set (insort x xs l)" by (simp add: NormalisationGenericProofs.set_insort) lemma sorted_insorta[rule_format]: assumes 1 : "sorted (insort x xs l) l" and 2 : "all_in_list (x#xs) l" and 3 : "all_in_list (x#xs) l" and 4 : "distinct (x#xs)" and 5 : "singleCombinators [x]" and 6 : "singleCombinators xs" shows "sorted xs l" proof (insert 1 2 3 4 5 6, induct xs) case Nil show ?case by simp next case (Cons a xs) then show ?case apply simp apply (auto intro: is_in_insort sorted_ConsA set_insort singleCombinators_insort singleCombinatorsConc sortedConcEnd all_in_list_insort) [1] apply(cases "smaller x a l", simp_all) by (metis NormalisationGenericProofs.set_insort NormalisationGenericProofs.sorted_Cons all_in_list.simps(2) all_in_list_insort aux0_1 insert_iff singleCombinatorsConc singleCombinatorsStart singleCombinators_insort) qed lemma sorted_insortb[rule_format]: "sorted xs l ⟶ all_in_list (x#xs) l ⟶ distinct (x#xs) ⟶ singleCombinators [x] ⟶ singleCombinators xs ⟶ sorted (insort x xs l) l" proof (induct xs) case Nil show ?case by simp_all next case (Cons a xs) have * : "sorted (a # xs) l ⟹ all_in_list (x # a # xs) l ⟹ distinct (x # a # xs) ⟹ singleCombinators [x] ⟹ singleCombinators (a # xs) ⟹ sorted (insort x xs l) l" apply(insert Cons.hyps, simp_all) apply(metis sorted_Cons all_in_list.simps(2) singleCombinatorsConc) done show ?case apply (insert Cons.hyps) apply (rule impI)+ apply (insert *, auto intro!: sorted_Consb) proof (rule_tac b = "x#xs" in all_in_listSubset) show "in_list x l ⟹ all_in_list xs l ⟹ all_in_list (x # xs) l" by simp_all next show "singleCombinators [x] ⟹ singleCombinators (a # xs) ⟹ FWNormalisationCore.sorted (FWNormalisationCore.insort x xs l) l ⟹ singleCombinators (FWNormalisationCore.insort x xs l)" apply (rule singleCombinators_insort, simp_all) by (erule singleCombinatorsConc) next show "set (FWNormalisationCore.insort x xs l) ⊆ set (x # xs)" using NormalisationGenericProofs.set_insort_insert by auto next show "singleCombinators [x] ⟹ singleCombinators (a # xs) ⟹ singleCombinators (a # FWNormalisationCore.insort x xs l)" by (metis SCConca singleCombinatorsConc singleCombinatorsStart singleCombinators_insort) next fix y show "FWNormalisationCore.sorted (a # xs) l ⟹ singleCombinators [x] ⟹ singleCombinators (a # xs) ⟹ in_list x l ⟹ in_list a l ⟹ all_in_list xs l ⟹ ¬ smaller x a l ⟹ y ∈ set (FWNormalisationCore.insort x xs l) ⟹ smaller a y l" by (metis NormalisationGenericProofs.set_insort in_set_in_list insert_iff singleCombinatorsConc singleCombinatorsStart smaller_antisym sorted_is_smaller) qed qed lemma sorted_insort: "⟦all_in_list (x#xs) l; distinct(x#xs); singleCombinators [x]; singleCombinators xs⟧ ⟹ sorted (insort x xs l) l = sorted xs l" by (auto intro: sorted_insorta sorted_insortb) lemma distinct_insort: "distinct (insort x xs l) = (x ∉ set xs ∧ distinct xs)" by(induct xs)(auto simp:set_insort) lemma distinct_sort[simp]: "distinct (sort xs l) = distinct xs" by(induct xs)(simp_all add:distinct_insort) lemma sort_is_sorted[rule_format]: "all_in_list p l ⟶ distinct p ⟶ singleCombinators p ⟶ sorted (sort p l) l" apply (induct p) apply simp by (metis (no_types, lifting) NormalisationGenericProofs.distinct_sort NormalisationGenericProofs.set_sort SC3 all_in_list.simps(2) all_in_listSubset distinct.simps(2) set_subset_Cons singleCombinatorsConc singleCombinatorsStart sort.simps(2) sorted_insortb) lemma smaller_sym[rule_format]: "all_in_list [a] l ⟶ smaller a a l" by (case_tac a,simp_all) lemma SC_sublist[rule_format]: "singleCombinators xs ⟹ singleCombinators (qsort [y←xs. P y] l)" by (auto intro: SCSubset) lemma all_in_list_sublist[rule_format]: "singleCombinators xs ⟶ all_in_list xs l ⟶ all_in_list (qsort [y←xs. P y] l) l" by (auto intro: all_in_listSubset SC_sublist) lemma SC_sublist2[rule_format]: "singleCombinators xs ⟶ singleCombinators ([y←xs. P y])" by (auto intro: SCSubset) lemma all_in_list_sublist2[rule_format]: "singleCombinators xs ⟶ all_in_list xs l ⟶ all_in_list ( [y←xs. P y]) l" by (auto intro: all_in_listSubset SC_sublist2) lemma all_in_listAppend[rule_format]: "all_in_list (xs) l ⟶ all_in_list (ys) l ⟶ all_in_list (xs @ ys) l" by (induct xs) simp_all lemma distinct_sortQ[rule_format]: "singleCombinators xs ⟶ all_in_list xs l ⟶ distinct xs ⟶ distinct (qsort xs l)" apply (induct xs l rule: qsort.induct) apply simp apply (auto simp: SC_sublist2 singleCombinatorsConc all_in_list_sublist2) done lemma singleCombinatorsAppend[rule_format]: "singleCombinators (xs) ⟶ singleCombinators (ys) ⟶ singleCombinators (xs @ ys)" apply (induct xs, auto) subgoal for a as apply (case_tac a,simp_all) done subgoal for a as apply (case_tac a,simp_all) done done lemma sorted_append1[rule_format]: "all_in_list xs l ⟶ singleCombinators xs ⟶ all_in_list ys l ⟶ singleCombinators ys ⟶ (sorted (xs@ys) l ⟶ (sorted xs l & sorted ys l & (∀x ∈ set xs. ∀y ∈ set ys. smaller x y l)))" apply(induct xs) apply(simp_all) by (metis NormalisationGenericProofs.sorted_Cons all_in_list.simps(2) all_in_listAppend aux0_1 aux0_4 singleCombinatorsAppend singleCombinatorsConc singleCombinatorsStart) lemma sorted_append2[rule_format]: "all_in_list xs l⟶ singleCombinators xs ⟶ all_in_list ys l ⟶ singleCombinators ys ⟶ (sorted xs l & sorted ys l & (∀x ∈ set xs. ∀y ∈ set ys. smaller x y l)) ⟶ (sorted (xs@ys) l)" apply (induct xs) apply simp_all by (metis NormalisationGenericProofs.sorted_Cons all_in_list.simps(2) all_in_listAppend aux0_1 aux0_4 singleCombinatorsAppend singleCombinatorsConc singleCombinatorsStart) lemma sorted_append[rule_format]: "all_in_list xs l ⟶ singleCombinators xs ⟶ all_in_list ys l ⟶ singleCombinators ys ⟶ (sorted (xs@ys) l) = (sorted xs l & sorted ys l & (∀x ∈ set xs. ∀y ∈ set ys. smaller x y l))" apply (rule impI)+ apply (rule iffI) apply (rule sorted_append1,simp_all) apply (rule sorted_append2,simp_all) done lemma sort_is_sortedQ[rule_format]: "all_in_list p l ⟶ singleCombinators p ⟶ sorted (qsort p l) l" proof (induct p l rule: qsort.induct) print_cases case 1 show ?case by simp next case 2 fix x::"('a,'b) Combinators" fix xs::"('a,'b) Combinators list" fix l show "all_in_list [y←xs . ¬ smaller x y l] l ⟶ singleCombinators [y←xs . ¬ smaller x y l] ⟶ sorted (qsort [y←xs . ¬ smaller x y l] l) l ⟹ all_in_list [y←xs . smaller x y l] l ⟶ singleCombinators [y←xs . smaller x y l] ⟶ sorted (qsort [y←xs . smaller x y l] l) l ⟹ all_in_list(x#xs) l ⟶ singleCombinators(x#xs) ⟶ sorted (qsort(x#xs) l) l" apply (intro impI) apply (simp_all add: SC_sublist all_in_list_sublist all_in_list_sublist2 singleCombinatorsConc SC_sublist2) proof (subst sorted_append) show "in_list x l ∧ all_in_list xs l ⟹ singleCombinators (x # xs) ⟹ all_in_list (qsort [y←xs . ¬ smaller x y l] l) l" by (metis all_in_list_sublist singleCombinatorsConc) next show "in_list x l ∧ all_in_list xs l ⟹ singleCombinators (x # xs) ⟹ singleCombinators (qsort [y←xs . ¬ smaller x y l] l)" apply (auto simp: SC_sublist all_in_list_sublist SC_sublist2 all_in_list_sublist2 sorted_Cons sorted_append not_le) apply (metis SC3Q SC_sublist2 singleCombinatorsConc) done next show "sorted (qsort [y←xs . ¬ smaller x y l] l) l ⟹ sorted (qsort [y←xs . smaller x y l] l) l ⟹ in_list x l ∧ all_in_list xs l ⟹ singleCombinators (x # xs) ⟹ all_in_list (x # qsort [y←xs . smaller x y l] l) l" using all_in_list.simps(2) all_in_list_sublist singleCombinatorsConc by blast next show "sorted (qsort [y←xs . smaller x y l] l) l ⟹ in_list x l ∧ all_in_list xs l ⟹ singleCombinators (x # xs) ⟹ singleCombinators (x # qsort [y←xs . smaller x y l] l)" using SC_sublist aux0_1 singleCombinatorsConc singleCombinatorsStart by blast next show "sorted (qsort [y←xs . ¬ smaller x y l] l) l ⟹ sorted (qsort [y←xs . smaller x y l] l) l ⟹ in_list x l ∧ all_in_list xs l ⟹ singleCombinators (x # xs) ⟹ FWNormalisationCore.sorted (qsort [y←xs . ¬ smaller x y l] l) l ∧ FWNormalisationCore.sorted (x # qsort [y←xs . smaller x y l] l) l ∧ (∀x'∈set (qsort [y←xs . ¬ smaller x y l] l). ∀y∈set (x # qsort [y←xs . smaller x y l] l). smaller x' y l)" apply(auto)[1] apply (metis (mono_tags, lifting) SC_sublist all_in_list.simps(2) all_in_list_sublist aux0_1 mem_Collect_eq set_filter set_qsort singleCombinatorsConc singleCombinatorsStart sorted_Consb) apply (metis aux0_0 aux0_6 in_set_in_list singleCombinatorsConc singleCombinatorsStart smaller_antisym) by (metis (no_types, lifting) NormalisationGenericProofs.order_trans aux0_0 aux0_6 in_set_in_list singleCombinatorsConc singleCombinatorsStart smaller_antisym) qed qed lemma inSet_not_MT: "a ∈ set p ⟹ p ≠ []" by auto lemma RS1n_assoc: "x ≠ DenyAll ⟹ removeShadowRules1_alternative xs @ [x] = removeShadowRules1_alternative (xs @ [x])" by (simp add: removeShadowRules1_alternative_def aux114) lemma RS1n_nMT[rule_format,simp]: "p ≠ []⟶ removeShadowRules1_alternative p ≠ []" apply (simp add: removeShadowRules1_alternative_def) apply (rule_tac xs = p in rev_induct, simp_all) subgoal for x xs apply (case_tac "xs = []", simp_all) apply (case_tac x, simp_all) apply (rule_tac xs = "xs" in rev_induct, simp_all) apply (case_tac x, simp_all)+ done done lemma RS1N_DA[simp]: "removeShadowRules1_alternative (a@[DenyAll]) = [DenyAll]" by (simp add: removeShadowRules1_alternative_def) lemma WP1n_DA_notinSet[rule_format]: "wellformed_policy1_strong p ⟶ DenyAll ∉ set (tl p)" by (induct p) (simp_all) lemma mt_sym: "dom a ∩ dom b = {} ⟹ dom b ∩ dom a = {}" by auto lemma DAnotTL[rule_format]: "xs ≠ [] ⟶ wellformed_policy1 (xs @ [DenyAll]) ⟶ False" by (induct xs, simp_all) lemma AND_tl[rule_format]: "allNetsDistinct ( p) ⟶ allNetsDistinct (tl p)" apply (induct p, simp_all) by (auto intro: ANDConc) lemma distinct_tl[rule_format]: "distinct p ⟶ distinct (tl p)" by (induct p, simp_all) lemma SC_tl[rule_format]: "singleCombinators ( p) ⟶ singleCombinators (tl p)" by (induct p, simp_all) (auto intro: singleCombinatorsConc) lemma Conc_not_MT: "p = x#xs ⟹ p ≠ []" by auto lemma wp1_tl[rule_format]: "p ≠ [] ∧ wellformed_policy1 p ⟶ wellformed_policy1 (tl p)" by (induct p) (auto intro: waux2) lemma wp1_eq[rule_format]: "wellformed_policy1_strong p ⟹ wellformed_policy1 p" apply (case_tac "DenyAll ∈ set p") apply (subst wellformed_eq) apply (auto elim: waux2) done lemma wellformed1_alternative_sorted: "wellformed_policy1_strong p ⟹ wellformed_policy1_strong (sort p l)" by (case_tac "p", simp_all) lemma wp1n_RS2[rule_format]: "wellformed_policy1_strong p ⟶ wellformed_policy1_strong (removeShadowRules2 p)" by (induct p, simp_all) lemma RS2_NMT[rule_format]: "p ≠ [] ⟶ removeShadowRules2 p ≠ []" apply (induct p, simp_all) subgoal for a p apply (case_tac "p ≠ []", simp_all) apply (case_tac "a", simp_all)+ done done lemma wp1_alternative_not_mt[simp]: "wellformed_policy1_strong p ⟹ p ≠ []" by auto lemma AIL1[rule_format,simp]: "all_in_list p l ⟶ all_in_list (removeShadowRules1 p) l" by (induct_tac p, simp_all) lemma wp1ID: "wellformed_policy1_strong (insertDeny (removeShadowRules1 p))" apply (induct p, simp_all) subgoal for a p apply (case_tac a, simp_all) done done lemma dRD[simp]: "distinct (remdups p)" by simp lemma AILrd[rule_format,simp]: "all_in_list p l ⟶ all_in_list (remdups p) l" by (induct p, simp_all) lemma AILiD[rule_format,simp]: "all_in_list p l ⟶ all_in_list (insertDeny p) l" apply (induct p, simp_all) apply (rule impI, simp) subgoal for a p apply (case_tac a, simp_all) done done lemma SCrd[rule_format,simp]:"singleCombinators p⟶ singleCombinators(remdups p)" apply (induct p, simp_all) subgoal for a p apply (case_tac a, simp_all) done done lemma SCRiD[rule_format,simp]: "singleCombinators p ⟶ singleCombinators(insertDeny p)" apply (induct p, simp_all) subgoal for a p apply (case_tac a, simp_all) done done lemma WP1rd[rule_format,simp]: "wellformed_policy1_strong p ⟶ wellformed_policy1_strong (remdups p)" by (induct p, simp_all) lemma ANDrd[rule_format,simp]: "singleCombinators p ⟶ allNetsDistinct p ⟶ allNetsDistinct (remdups p)" apply (rule impI)+ apply (rule_tac b = p in aNDSubset) apply simp_all done lemma ANDiD[rule_format,simp]: "allNetsDistinct p ⟶ allNetsDistinct (insertDeny p)" apply (induct p, simp_all) apply (simp add: allNetsDistinct_def) apply (auto intro: ANDConc) subgoal for a p apply (case_tac "a",simp_all add: allNetsDistinct_def) done done lemma mr_iD[rule_format]: "wellformed_policy1_strong p ⟶ matching_rule x p = matching_rule x (insertDeny p)" by (induct p, simp_all) lemma WP1iD[rule_format,simp]: "wellformed_policy1_strong p ⟶ wellformed_policy1_strong (insertDeny p)" by (induct p, simp_all) lemma DAiniD: "DenyAll ∈ set (insertDeny p)" apply (induct p, simp_all) subgoal for a p apply(case_tac a, simp_all) done done lemma p2lNmt: "policy2list p ≠ []" by (rule policy2list.induct, simp_all) lemma AIL2[rule_format,simp]: "all_in_list p l ⟶ all_in_list (removeShadowRules2 p) l" apply (induct_tac p, simp_all) subgoal for a p apply(case_tac a, simp_all) done done lemma SCConc: "singleCombinators x ⟹ singleCombinators y ⟹ singleCombinators (x@y)" apply (rule aux0_5) apply (metis aux0_0 aux0_4) done lemma SCp2l: "singleCombinators (policy2list p)" by (induct_tac p) (auto intro: SCConc) lemma subnetAux: "Dd ∩ A ≠ {} ⟹ A ⊆ B ⟹ Dd ∩ B ≠ {}" by auto lemma soadisj: "x ∈ subnetsOfAdr a ⟹ y ∈ subnetsOfAdr a ⟹ ¬ netsDistinct x y" by(simp add: subnetsOfAdr_def netsDistinct_def,auto) lemma not_member: "¬ member a (x⊕y) ⟹ ¬ member a x" by auto lemma soadisj2: "(∀ a x y. x ∈ subnetsOfAdr a ∧ y ∈ subnetsOfAdr a ⟶ ¬ netsDistinct x y)" by (simp add: subnetsOfAdr_def netsDistinct_def, auto) lemma ndFalse1: "(∀a b c d. (a,b)∈A ∧ (c,d)∈B ⟶ netsDistinct a c) ⟹ ∃(a, b)∈A. a ∈ subnetsOfAdr D ⟹ ∃(a, b)∈B. a ∈ subnetsOfAdr D ⟹ False" apply (auto simp: soadisj) using soadisj2 by blast lemma ndFalse2: "(∀a b c d. (a,b)∈A ∧ (c,d)∈B ⟶ netsDistinct b d) ⟹ ∃(a, b)∈A. b ∈ subnetsOfAdr D ⟹ ∃(a, b)∈B. b ∈ subnetsOfAdr D ⟹ False" apply (auto simp: soadisj) using soadisj2 by blast lemma tndFalse: "(∀a b c d. (a,b)∈A ∧ (c,d)∈B ⟶ twoNetsDistinct a b c d) ⟹ ∃(a, b)∈A. a ∈ subnetsOfAdr (D::('a::adr)) ∧ b ∈ subnetsOfAdr (F::'a) ⟹ ∃(a, b)∈B. a ∈ subnetsOfAdr D∧ b∈ subnetsOfAdr F ⟹ False" apply (simp add: twoNetsDistinct_def) apply (auto simp: ndFalse1 ndFalse2) apply (metis soadisj) done lemma sepnMT[rule_format]: "p ≠ [] ⟶ (separate p) ≠ []" by (induct p rule: separate.induct) simp_all lemma sepDA[rule_format]: "DenyAll ∉ set p ⟶ DenyAll ∉ set (separate p)" by (induct p rule: separate.induct) simp_all lemma setnMT: "set a = set b ⟹ a ≠ [] ⟹ b ≠ []" by auto lemma sortnMT: "p ≠ [] ⟹ sort p l ≠ []" by (metis set_sort setnMT) lemma idNMT[rule_format]: "p ≠ [] ⟶ insertDenies p ≠ []" apply (induct p, simp_all) subgoal for a p apply(case_tac a, simp_all) done done lemma OTNoTN[rule_format]: " OnlyTwoNets p ⟶ x ≠ DenyAll ⟶ x ∈ set p ⟶ onlyTwoNets x" apply (induct p, simp_all, rename_tac a p) apply (intro impI conjI, simp) subgoal for a p apply(case_tac a, simp_all) done subgoal for a p apply(case_tac a, simp_all) done done lemma first_isIn[rule_format]: "¬ member DenyAll x ⟶ (first_srcNet x,first_destNet x) ∈ sdnets x" by (induct x,case_tac x, simp_all) lemma sdnets2: "∃a b. sdnets x = {(a, b), (b, a)} ⟹ ¬ member DenyAll x ⟹ sdnets x = {(first_srcNet x, first_destNet x), (first_destNet x, first_srcNet x)}" proof - have * : "∃a b. sdnets x = {(a, b), (b, a)} ⟹ ¬ member DenyAll x ⟹ (first_srcNet x, first_destNet x) ∈ sdnets x" by (erule first_isIn) show "∃a b. sdnets x = {(a, b), (b, a)} ⟹ ¬ member DenyAll x ⟹ sdnets x = {(first_srcNet x, first_destNet x), (first_destNet x, first_srcNet x)}" using * by auto qed lemma alternativelistconc1[rule_format]: "a ∈ set (net_list_aux [x]) ⟶ a ∈ set (net_list_aux [x,y])" by (induct x,simp_all) lemma alternativelistconc2[rule_format]: "a ∈ set (net_list_aux [x]) ⟶ a ∈ set (net_list_aux [y,x])" by (induct y, simp_all) lemma noDA[rule_format]: "noDenyAll xs ⟶ s ∈ set xs ⟶ ¬ member DenyAll s" by (induct xs, simp_all) lemma isInAlternativeList: "(aa ∈ set (net_list_aux [a]) ∨ aa ∈ set (net_list_aux p)) ⟹ aa ∈ set (net_list_aux (a # p))" by (case_tac a,simp_all) lemma netlistaux: "x ∈ set (net_list_aux (a # p))⟹ x ∈ set (net_list_aux ([a])) ∨ x ∈ set (net_list_aux (p))" apply (case_tac " x ∈ set (net_list_aux [a])", simp_all) apply (case_tac a, simp_all) done lemma firstInNet[rule_format]: "¬ member DenyAll a ⟶ first_destNet a ∈ set (net_list_aux (a # p))" apply (rule Combinators.induct, simp_all) apply (metis netlistaux) done lemma firstInNeta[rule_format]: "¬ member DenyAll a ⟶ first_srcNet a ∈ set (net_list_aux (a # p))" apply (rule Combinators.induct, simp_all) apply (metis netlistaux) done lemma disjComm: "disjSD_2 a b ⟹ disjSD_2 b a" apply (simp add: disjSD_2_def) apply (intro allI impI conjI) using tNDComm apply blast by (meson tNDComm twoNetsDistinct_def) lemma disjSD2aux: "disjSD_2 a b ⟹ ¬ member DenyAll a ⟹ ¬ member DenyAll b ⟹ disjSD_2 (DenyAllFromTo (first_srcNet a) (first_destNet a) ⊕ DenyAllFromTo (first_destNet a) (first_srcNet a) ⊕ a) b" apply (drule disjComm,rule disjComm) apply (simp add: disjSD_2_def) using first_isIn by blast lemma noDA1eq[rule_format]: "noDenyAll p ⟶ noDenyAll1 p" apply (induct p, simp,rename_tac a p) subgoal for a p apply(case_tac a, simp_all) done done lemma noDA1C[rule_format]: "noDenyAll1 (a#p) ⟶ noDenyAll1 p" by (case_tac a, simp_all,rule impI, rule noDA1eq, simp)+ lemma disjSD_2IDa: "disjSD_2 x y ⟹ ¬ member DenyAll x ⟹ ¬ member DenyAll y ⟹ a = first_srcNet x ⟹ b = first_destNet x ⟹ disjSD_2 (DenyAllFromTo a b ⊕ DenyAllFromTo b a ⊕ x) y" by(simp add:disjSD2aux) lemma noDAID[rule_format]: "noDenyAll p ⟶ noDenyAll (insertDenies p)" apply (induct p, simp_all) subgoal for a p apply(case_tac a, simp_all) done done lemma isInIDo[rule_format]: "noDenyAll p ⟶ s ∈ set (insertDenies p) ⟶ (∃! a. s = (DenyAllFromTo (first_srcNet a) (first_destNet a)) ⊕ (DenyAllFromTo (first_destNet a) (first_srcNet a)) ⊕ a ∧ a ∈ set p)" apply (induct p, simp, rename_tac a p) subgoal for a p apply (case_tac "a = DenyAll", simp) apply (case_tac a, auto) done done lemma id_aux1[rule_format]: "DenyAllFromTo (first_srcNet s) (first_destNet s) ⊕ DenyAllFromTo (first_destNet s) (first_srcNet s) ⊕ s∈ set (insertDenies p) ⟶ s ∈ set p" apply (induct p, simp_all, rename_tac a p) subgoal for a p apply(case_tac a, simp_all) done done lemma id_aux2: "noDenyAll p ⟹ ∀s. s ∈ set p ⟶ disjSD_2 a s ⟹ ¬ member DenyAll a ⟹ DenyAllFromTo (first_srcNet s) (first_destNet s) ⊕ DenyAllFromTo (first_destNet s) (first_srcNet s) ⊕ s ∈ set (insertDenies p) ⟹ disjSD_2 a (DenyAllFromTo (first_srcNet s) (first_destNet s) ⊕ DenyAllFromTo (first_destNet s) (first_srcNet s) ⊕ s)" by (metis disjComm disjSD2aux isInIDo noDA) lemma id_aux4[rule_format]: "noDenyAll p ⟹ ∀s. s ∈ set p ⟶ disjSD_2 a s ⟹ s ∈ set (insertDenies p) ⟹ ¬ member DenyAll a ⟹ disjSD_2 a s" apply (subgoal_tac "∃a. s = DenyAllFromTo (first_srcNet a) (first_destNet a) ⊕ DenyAllFromTo (first_destNet a) (first_srcNet a) ⊕ a ∧ a ∈ set p") apply (drule_tac Q = "disjSD_2 a s" in exE, simp_all, rule id_aux2, simp_all) using isInIDo by blast lemma sepNetsID[rule_format]: "noDenyAll1 p ⟶ separated p ⟶ separated (insertDenies p)" apply (induct p, simp) apply (rename_tac a p, auto) using noDA1C apply blast subgoal for a p apply (case_tac "a = DenyAll", auto) apply (simp add: disjSD_2_def) apply (case_tac a,auto) apply (rule disjSD_2IDa, simp_all, rule id_aux4, simp_all, metis noDA noDAID)+ done done lemma aNDDA[rule_format]: "allNetsDistinct p ⟶ allNetsDistinct(DenyAll#p)" by (case_tac p,auto simp: allNetsDistinct_def) lemma OTNConc[rule_format]: "OnlyTwoNets (y # z) ⟶ OnlyTwoNets z" by (case_tac y, simp_all) lemma first_bothNetsd: "¬ member DenyAll x ⟹ first_bothNet x = {first_srcNet x, first_destNet x}" by (induct x) simp_all lemma bNaux: "¬ member DenyAll x ⟹ ¬ member DenyAll y ⟹ first_bothNet x = first_bothNet y ⟹ {first_srcNet x, first_destNet x} = {first_srcNet y, first_destNet y}" by (simp add: first_bothNetsd) lemma setPair: "{a,b} = {a,d} ⟹ b = d" by (metis setPaireq) lemma setPair1: "{a,b} = {d,a} ⟹ b = d" by (metis Un_empty_right Un_insert_right insert_absorb2 setPaireq) lemma setPair4: "{a,b} = {c,d} ⟹ a ≠ c ⟹ a = d" by auto lemma otnaux1: " {x, y, x, y} = {x,y}" by auto lemma OTNIDaux4: "{x,y,x} = {y,x}" by auto lemma setPair5: "{a,b} = {c,d} ⟹ a ≠ c ⟹ a = d" by auto lemma otnaux: " ⟦first_bothNet x = first_bothNet y; ¬ member DenyAll x; ¬ member DenyAll y; onlyTwoNets y; onlyTwoNets x⟧ ⟹ onlyTwoNets (x ⊕ y)" apply (simp add: onlyTwoNets_def) apply (subgoal_tac "{first_srcNet x, first_destNet x} = {first_srcNet y, first_destNet y}") apply (case_tac "(∃a b. sdnets y = {(a, b)})") apply simp_all apply (case_tac "(∃a b. sdnets x = {(a, b)})") apply simp_all apply (subgoal_tac "sdnets x = {(first_srcNet x, first_destNet x)}") apply (subgoal_tac "sdnets y = {(first_srcNet y, first_destNet y)}") apply simp apply (case_tac "first_srcNet x = first_srcNet y") apply simp_all apply (rule disjI1) apply (rule setPair) apply simp apply (subgoal_tac "first_srcNet x = first_destNet y") apply simp apply (subgoal_tac "first_destNet x = first_srcNet y") apply simp apply (rule_tac x ="first_srcNet y" in exI, rule_tac x = "first_destNet y" in exI,simp) apply (rule setPair1) apply simp apply (rule setPair4) apply simp_all apply (metis first_isIn singletonE) apply (metis first_isIn singletonE) apply (subgoal_tac "sdnets x = {(first_srcNet x, first_destNet x), (first_destNet x, first_srcNet x)}") apply (subgoal_tac "sdnets y = {(first_srcNet y, first_destNet y)}") apply simp apply (case_tac "first_srcNet x = first_srcNet y") apply simp_all apply (subgoal_tac "first_destNet x = first_destNet y") apply simp apply (rule setPair) apply simp apply (subgoal_tac "first_srcNet x = first_destNet y") apply simp apply (subgoal_tac "first_destNet x = first_srcNet y") apply simp apply (rule_tac x ="first_srcNet y" in exI, rule_tac x = "first_destNet y" in exI) apply (metis OTNIDaux4 insert_commute ) apply (rule setPair1) apply simp apply (rule setPair5) apply assumption apply simp apply (metis first_isIn singletonE) apply (rule sdnets2) apply simp_all apply (case_tac "(∃a b. sdnets x = {(a, b)})") apply simp_all apply (subgoal_tac "sdnets x = {(first_srcNet x, first_destNet x)}") apply (subgoal_tac "sdnets y = {(first_srcNet y, first_destNet y), (first_destNet y, first_srcNet y)}") apply simp apply (case_tac "first_srcNet x = first_srcNet y") apply simp_all apply (subgoal_tac "first_destNet x = first_destNet y") apply simp apply (rule_tac x ="first_srcNet y" in exI, rule_tac x = "first_destNet y" in exI) apply (metis OTNIDaux4 insert_commute ) apply (rule setPair) apply simp apply (subgoal_tac "first_srcNet x = first_destNet y") apply simp apply (subgoal_tac "first_destNet x = first_srcNet y") apply simp apply (rule setPair1) apply simp apply (rule setPair4) apply assumption apply simp apply (rule sdnets2) apply simp apply simp apply (metis singletonE first_isIn) apply (subgoal_tac "sdnets x = {(first_srcNet x, first_destNet x), (first_destNet x, first_srcNet x)}") apply (subgoal_tac "sdnets y = {(first_srcNet y, first_destNet y), (first_destNet y, first_srcNet y)}") apply simp apply (case_tac "first_srcNet x = first_srcNet y") apply simp_all apply (subgoal_tac "first_destNet x = first_destNet y") apply simp apply (rule_tac x ="first_srcNet y" in exI, rule_tac x = "first_destNet y" in exI) apply (rule otnaux1) apply (rule setPair) apply simp apply (subgoal_tac "first_srcNet x = first_destNet y") apply simp apply (subgoal_tac "first_destNet x = first_srcNet y") apply simp apply (rule_tac x ="first_srcNet y" in exI, rule_tac x = "first_destNet y" in exI) apply (metis OTNIDaux4 insert_commute) apply (rule setPair1) apply simp apply (rule setPair4) apply assumption apply simp apply (rule sdnets2,simp_all)+ apply (rule bNaux, simp_all) done lemma OTNSepaux: "onlyTwoNets (a ⊕ y) ∧ OnlyTwoNets z ⟶ OnlyTwoNets (separate (a ⊕ y # z)) ⟹ ¬ member DenyAll a ⟹ ¬ member DenyAll y ⟹ noDenyAll z ⟹ onlyTwoNets a ⟹ OnlyTwoNets (y # z) ⟹ first_bothNet a = first_bothNet y ⟹ OnlyTwoNets (separate (a ⊕ y # z))" apply (drule mp) apply simp_all apply (rule conjI) apply (rule otnaux) apply simp_all apply (rule_tac p = "(y # z)" in OTNoTN) apply simp_all apply (metis member.simps(2)) apply (simp add: onlyTwoNets_def) apply (rule_tac y = y in OTNConc,simp) done lemma OTNSEp[rule_format]: "noDenyAll1 p ⟶ OnlyTwoNets p ⟶ OnlyTwoNets (separate p)" apply (induct p rule: separate.induct) by (simp_all add: OTNSepaux noDA1eq) lemma nda[rule_format]: "singleCombinators (a#p) ⟶ noDenyAll p ⟶ noDenyAll1 (a # p)" apply (induct p,simp_all) apply (case_tac a, simp_all)+ done lemma nDAcharn[rule_format]: "noDenyAll p = (∀ r ∈ set p. ¬ member DenyAll r)" by (induct p, simp_all) lemma nDAeqSet: "set p = set s ⟹ noDenyAll p = noDenyAll s" by (simp add: nDAcharn) lemma nDASCaux[rule_format]: "DenyAll ∉ set p ⟶ singleCombinators p ⟶ r ∈ set p ⟶ ¬ member DenyAll r" apply (case_tac r, simp_all) using SCnotConc by blast lemma nDASC[rule_format]: "wellformed_policy1 p ⟶ singleCombinators p ⟶ noDenyAll1 p" apply (induct p, simp_all) using nDASCaux nDAcharn nda singleCombinatorsConc by blast lemma noDAAll[rule_format]: "noDenyAll p = (¬ memberP DenyAll p)" by (induct p) simp_all lemma memberPsep[symmetric]: "memberP x p = memberP x (separate p)" by (induct p rule: separate.induct) simp_all lemma noDAsep[rule_format]: "noDenyAll p ⟹ noDenyAll (separate p)" by (simp add:noDAAll,subst memberPsep, simp) lemma noDA1sep[rule_format]: "noDenyAll1 p ⟶ noDenyAll1 (separate p)" by (induct p rule:separate.induct, simp_all add: noDAsep) lemma isInAlternativeLista: "(aa ∈ set (net_list_aux [a]))⟹ aa ∈ set (net_list_aux (a # p))" by (case_tac a,auto) lemma isInAlternativeListb: "(aa ∈ set (net_list_aux p))⟹ aa ∈ set (net_list_aux (a # p))" by (case_tac a,simp_all) lemma ANDSepaux: "allNetsDistinct (x # y # z) ⟹ allNetsDistinct (x ⊕ y # z)" apply (simp add: allNetsDistinct_def) apply (intro allI impI, rename_tac a b) subgoal for a b apply (drule_tac x = a in spec, drule_tac x = b in spec) by (meson isInAlternativeList) done lemma netlistalternativeSeparateaux: "net_list_aux [y] @ net_list_aux z = net_list_aux (y # z)" by (case_tac y, simp_all) lemma netlistalternativeSeparate: "net_list_aux p = net_list_aux (separate p)" by (induct p rule:separate.induct, simp_all) (simp_all add: netlistalternativeSeparateaux) lemma ANDSepaux2: "allNetsDistinct(x#y#z) ⟹ allNetsDistinct(separate(y#z)) ⟹ allNetsDistinct(x#separate(y#z))" apply (simp add: allNetsDistinct_def) by (metis isInAlternativeList netlistalternativeSeparate netlistaux) lemma ANDSep[rule_format]: "allNetsDistinct p ⟶ allNetsDistinct(separate p)" apply (induct p rule: separate.induct, simp_all) apply (metis ANDConc aNDDA) apply (metis ANDConc ANDSepaux ANDSepaux2) apply (metis ANDConc ANDSepaux ANDSepaux2) apply (metis ANDConc ANDSepaux ANDSepaux2) done lemma wp1_alternativesep[rule_format]: "wellformed_policy1_strong p ⟶ wellformed_policy1_strong (separate p)" by (metis sepDA separate.simps(1) wellformed_policy1_strong.simps(2) wp1n_tl) lemma noDAsort[rule_format]: "noDenyAll1 p ⟶ noDenyAll1 (sort p l)" apply (case_tac "p",simp_all) subgoal for a as apply (case_tac "a = DenyAll", auto) using NormalisationGenericProofs.set_sort nDAeqSet apply blast proof - fix a::"('a,'b)Combinators" fix list have * : "a ≠ DenyAll ⟹ noDenyAll1 (a # list) ⟹ noDenyAll (a#list)" by (case_tac a, simp_all) show "a ≠ DenyAll ⟹ noDenyAll1 (a # list) ⟹ noDenyAll1 (insort a (sort list l) l)" apply(cases "insort a (sort list l) l", simp_all) by (metis "*" NormalisationGenericProofs.set_insort NormalisationGenericProofs.set_sort list.simps(15) nDAeqSet noDA1eq) qed done lemma OTNSC[rule_format]: "singleCombinators p ⟶ OnlyTwoNets p" apply (induct p,simp_all) apply (rename_tac a p) apply (rule impI,drule mp) apply (erule singleCombinatorsConc) subgoal for a b apply (case_tac a, simp_all) apply (simp add: onlyTwoNets_def)+ done done lemma fMTaux: "¬ member DenyAll x ⟹ first_bothNet x ≠ {}" by (metis first_bothNetsd insert_commute insert_not_empty) lemma fl2[rule_format]: "firstList (separate p) = firstList p" by (rule separate.induct) simp_all lemma fl3[rule_format]: "NetsCollected p ⟶ (first_bothNet x ≠ firstList p ⟶ (∀a∈set p. first_bothNet x ≠ first_bothNet a))⟶ NetsCollected (x#p)" by (induct p) simp_all lemma sortedConc[rule_format]: " sorted (a # p) l ⟶ sorted p l" by (induct p) simp_all lemma smalleraux2: "{a,b} ∈ set l ⟹ {c,d} ∈ set l ⟹ {a,b} ≠ {c,d} ⟹ smaller (DenyAllFromTo a b) (DenyAllFromTo c d) l ⟹ ¬ smaller (DenyAllFromTo c d) (DenyAllFromTo a b) l" by (metis bothNet.simps(2) pos_noteq smaller.simps(5)) lemma smalleraux2a: "{a,b} ∈ set l ⟹ {c,d} ∈ set l ⟹ {a,b} ≠ {c,d} ⟹ smaller (DenyAllFromTo a b) (AllowPortFromTo c d p) l ⟹ ¬ smaller (AllowPortFromTo c d p) (DenyAllFromTo a b) l" by (simp) (metis eq_imp_le pos_noteq) lemma smalleraux2b: "{a,b} ∈ set l ⟹ {c,d} ∈ set l ⟹ {a,b} ≠ {c,d} ⟹ y = DenyAllFromTo a b ⟹ smaller (AllowPortFromTo c d p) y l ⟹ ¬ smaller y (AllowPortFromTo c d p) l" by (simp) (metis eq_imp_le pos_noteq) lemma smalleraux2c: "{a,b} ∈ set l⟹{c,d}∈set l⟹{a,b} ≠ {c,d} ⟹ y = AllowPortFromTo a b q ⟹ smaller (AllowPortFromTo c d p) y l ⟹ ¬ smaller y (AllowPortFromTo c d p) l" by (simp) (metis pos_noteq) lemma smalleraux3: assumes "x ∈ set l" and " y ∈ set l" and "x ≠ y" and "x = bothNet a" and "y = bothNet b" and "smaller a b l" and "singleCombinators [a]" and "singleCombinators [b]" shows "¬ smaller b a l" proof (cases a) case DenyAll thus ?thesis using assms by (case_tac b,simp_all) next case (DenyAllFromTo c d) thus ?thesis proof (cases b) case DenyAll thus ?thesis using assms DenyAll DenyAllFromTo by simp next case (DenyAllFromTo e f) thus ?thesis using assms DenyAllFromTo by (metis DenyAllFromTo ‹a = DenyAllFromTo c d› bothNet.simps(2) smalleraux2) next case (AllowPortFromTo e f g) thus ?thesis using assms DenyAllFromTo AllowPortFromTo by simp (metis eq_imp_le pos_noteq) next case (Conc e f) thus ?thesis using assms by simp qed next case (AllowPortFromTo c d p) thus ?thesis proof (cases b) case DenyAll thus ?thesis using assms AllowPortFromTo DenyAll by simp next case (DenyAllFromTo e f) thus ?thesis using assms by simp (metis AllowPortFromTo DenyAllFromTo bothNet.simps(3) smalleraux2a) next case (AllowPortFromTo e f g) thus ?thesis using assms by(simp)(metis AllowPortFromTo ‹a = AllowPortFromTo c d p› bothNet.simps(3) smalleraux2c) next case (Conc e f) thus ?thesis using assms by simp qed next case (Conc c d) thus ?thesis using assms by simp qed lemma smalleraux3a: "a ≠ DenyAll ⟹ b ≠ DenyAll ⟹ in_list b l ⟹ in_list a l ⟹ bothNet a ≠ bothNet b ⟹ smaller a b l ⟹ singleCombinators [a] ⟹ singleCombinators [b] ⟹ ¬ smaller b a l" apply (rule smalleraux3,simp_all) apply (case_tac a, simp_all) apply (case_tac b, simp_all) done lemma posaux[rule_format]: "position a l < position b l ⟶ a ≠ b" by (induct l, simp_all) lemma posaux6[rule_format]: "a ∈ set l ⟶ b ∈ set l ⟶ a ≠ b ⟶ position a l ≠ position b l" by (induct l) (simp_all add: position_positive) lemma notSmallerTransaux[rule_format]: "x ≠ DenyAll ⟹ r ≠ DenyAll ⟹ singleCombinators [x] ⟹ singleCombinators [y] ⟹ singleCombinators [r] ⟹ ¬ smaller y x l ⟹ smaller x y l ⟹ smaller x r l ⟹ smaller y r l ⟹ in_list x l ⟹ in_list y l ⟹ in_list r l ⟹ ¬ smaller r x l" by (metis order_trans) lemma notSmallerTrans[rule_format]: "x ≠ DenyAll ⟶ r ≠ DenyAll ⟶ singleCombinators (x#y#z) ⟶ ¬ smaller y x l ⟶ sorted (x#y#z) l ⟶ r ∈ set z ⟶ all_in_list (x#y#z) l ⟶ ¬ smaller r x l" apply (rule impI)+ apply (rule notSmallerTransaux, simp_all) apply (metis singleCombinatorsConc singleCombinatorsStart) apply (metis SCSubset equalityE remdups.simps(2) set_remdups singleCombinatorsConc singleCombinatorsStart) apply metis apply (metis sorted.simps(3) in_set_in_list singleCombinatorsConc singleCombinatorsStart sortedConcStart sorted_is_smaller) apply (metis sorted_Cons all_in_list.simps(2) singleCombinatorsConc) apply (metis,metis in_set_in_list) done lemma NCSaux1[rule_format]: "noDenyAll p ⟶ {x, y} ∈ set l ⟶ all_in_list p l⟶ singleCombinators p ⟶ sorted (DenyAllFromTo x y # p) l ⟶ {x, y} ≠ firstList p ⟶ DenyAllFromTo u v ∈ set p ⟶ {x, y} ≠ {u, v}" proof (cases p) case Nil thus ?thesis by simp next case (Cons a list) then show ?thesis apply simp apply (intro impI conjI) apply (metis bothNet.simps(2) first_bothNet.simps(3)) proof - assume 1: "{x, y} ∈ set l" and 2: "in_list a l ∧ all_in_list list l" and 3 : "singleCombinators (a # list)" and 4 : "smaller (DenyAllFromTo x y) a l ∧ sorted (a # list) l" and 5 : "DenyAllFromTo u v ∈ set list" and 6 : "¬ member DenyAll a ∧ noDenyAll list" have * : "smaller ((DenyAllFromTo x y)::(('a,'b)Combinators)) (DenyAllFromTo u v) l" apply (insert 1 2 3 4 5, rule_tac y = a in order_trans, simp_all) using in_set_in_list apply fastforce by (simp add: sorted_ConsA) have ** :"{x, y} ≠ first_bothNet a ⟹ ¬ smaller ((DenyAllFromTo u v)::('a, 'b) Combinators) (DenyAllFromTo x y) l" apply (insert 1 2 3 4 5 6, rule_tac y = "a" and z = "list" in notSmallerTrans, simp_all del: smaller.simps) apply (rule smalleraux3a,simp_all del: smaller.simps) apply (case_tac a, simp_all del: smaller.simps) by (metis aux0_0 first_bothNet.elims list.set_intros(1)) show " {x, y} ≠ first_bothNet a ⟹ {x, y} ≠ {u, v}" using 3 "*" "**" by force qed qed lemma posaux3[rule_format]:"a ∈ set l ⟶ b ∈ set l ⟶ a ≠ b ⟶ position a l ≠ position b l" apply (induct l, auto) by(metis position_positive)+ lemma posaux4[rule_format]: "singleCombinators [a] ⟶ a≠ DenyAll ⟶ b ≠ DenyAll ⟶ in_list a l ⟶in_list b l ⟶ smaller a b l⟶ x = (bothNet a) ⟶ y = (bothNet b) ⟶ position x l <= position y l" proof (cases a) case DenyAll then show ?thesis by simp next case (DenyAllFromTo c d) thus ?thesis proof (cases b) case DenyAll thus ?thesis by simp next case (DenyAllFromTo e f) thus ?thesis using DenyAllFromTo by (auto simp: eq_imp_le ‹a = DenyAllFromTo c d›) next case (AllowPortFromTo e f p) thus ?thesis using ‹a = DenyAllFromTo c d› by simp next case (Conc e f) thus ?thesis using Conc ‹a = DenyAllFromTo c d› by simp qed next case (AllowPortFromTo c d p) thus ?thesis proof (cases b) case DenyAll thus ?thesis by simp next case (DenyAllFromTo e f) thus ?thesis using AllowPortFromTo by simp next case (AllowPortFromTo e f p2) thus ?thesis using ‹a = AllowPortFromTo c d p› by simp next case (Conc e f) thus ?thesis using AllowPortFromTo by simp qed next case (Conc c d) thus ?thesis by simp qed lemma NCSaux2[rule_format]: "noDenyAll p ⟶ {a, b} ∈ set l ⟶ all_in_list p l ⟶singleCombinators p ⟶ sorted (DenyAllFromTo a b # p) l ⟶ {a, b} ≠ firstList p ⟶ AllowPortFromTo u v w ∈ set p ⟶ {a, b} ≠ {u, v}" proof (cases p) case Nil then show ?thesis by simp next case (Cons aa list) have * : "{a, b} ∈ set l ⟹ in_list aa l ∧ all_in_list list l ⟹ singleCombinators (aa # list) ⟹ AllowPortFromTo u v w ∈ set list ⟹ smaller (DenyAllFromTo a b) aa l ∧ sorted (aa # list) l ⟹ smaller (DenyAllFromTo a b) (AllowPortFromTo u v w) l" apply (rule_tac y = aa in order_trans,simp_all del: smaller.simps) using in_set_in_list apply fastforce using NormalisationGenericProofs.sorted_Cons all_in_list.simps(2) by blast have **: "AllowPortFromTo u v w ∈ set list ⟹ in_list aa l ⟹ all_in_list list l ⟹ in_list (AllowPortFromTo u v w) l" apply (rule_tac p = list in in_set_in_list) apply simp_all done assume "p = aa # list" then show ?thesis apply simp apply (intro impI conjI,hypsubst, simp) apply (subgoal_tac "smaller (DenyAllFromTo a b) (AllowPortFromTo u v w) l") apply (subgoal_tac "¬ smaller (AllowPortFromTo u v w) (DenyAllFromTo a b) l") apply (rule_tac l = l in posaux) apply (rule_tac y = "position (first_bothNet aa) l" in basic_trans_rules(22)) apply (simp_all split: if_splits) apply (case_tac aa, simp_all) subgoal for x x' apply (case_tac "a = x ∧ b = x'", simp_all) apply (case_tac "a = x", simp_all) apply (simp add: order.not_eq_order_implies_strict posaux6) apply (simp add: order.not_eq_order_implies_strict posaux6) done apply (simp add: order.not_eq_order_implies_strict posaux6) apply (rule basic_trans_rules(18)) apply (rule_tac a = "DenyAllFromTo a b" and b = aa in posaux4, simp_all) apply (case_tac aa,simp_all) apply (case_tac aa, simp_all) apply (rule posaux3, simp_all) apply (case_tac aa, simp_all) apply (rule_tac a = aa and b = "AllowPortFromTo u v w" in posaux4, simp_all) apply (case_tac aa,simp_all) apply (rule_tac p = list in sorted_is_smaller, simp_all) apply (case_tac aa, simp_all) apply (case_tac aa, simp_all) apply (rule_tac a = aa and b = "AllowPortFromTo u v w" in posaux4, simp_all) apply (case_tac aa,simp_all) using ** apply auto[1] apply (metis all_in_list.simps(2) sorted_Cons) apply (case_tac aa, simp_all) apply (metis ** bothNet.simps(3) in_list.simps(3) posaux6) using * by force qed lemma NCSaux3[rule_format]: "noDenyAll p ⟶ {a, b} ∈ set l ⟶ all_in_list p l ⟶singleCombinators p ⟶ sorted (AllowPortFromTo a b w # p) l ⟶ {a, b} ≠ firstList p ⟶ DenyAllFromTo u v ∈ set p ⟶ {a, b} ≠ {u, v}" apply (case_tac p, simp_all,intro impI conjI,hypsubst,simp) proof - fix aa::"('a, 'b) Combinators" fix list::"('a, 'b) Combinators list" assume 1 : "¬ member DenyAll aa ∧ noDenyAll list" and 2: "{a, b} ∈ set l " and 3 : "in_list aa l ∧ all_in_list list l" and 4: "singleCombinators (aa # list)" and 5 : "smaller (AllowPortFromTo a b w) aa l ∧ sorted (aa # list) l" and 6 : "{a, b} ≠ first_bothNet aa" and 7: "DenyAllFromTo u v ∈ set list" have *: "¬ smaller (DenyAllFromTo u v) (AllowPortFromTo a b w) l" apply (insert 1 2 3 4 5 6 7, rule_tac y = aa and z = list in notSmallerTrans) apply (simp_all del: smaller.simps) apply (rule smalleraux3a,simp_all del: smaller.simps) apply (case_tac aa, simp_all del: smaller.simps) apply (case_tac aa, simp_all del: smaller.simps) done have **: "smaller (AllowPortFromTo a b w) (DenyAllFromTo u v) l" apply (insert 1 2 3 4 5 6 7,rule_tac y = aa in order_trans,simp_all del: smaller.simps) apply (subgoal_tac "in_list (DenyAllFromTo u v) l", simp) apply (rule_tac p = list in in_set_in_list, simp_all) apply (rule_tac p = list in sorted_is_smaller,simp_all del: smaller.simps) apply (subgoal_tac "in_list (DenyAllFromTo u v) l", simp) apply (rule_tac p = list in in_set_in_list, simp_all) apply (erule singleCombinatorsConc) done show "{a, b} ≠ {u, v}" by (insert * **, simp split: if_splits) qed lemma NCSaux4[rule_format]: "noDenyAll p ⟶ {a, b} ∈ set l ⟶ all_in_list p l ⟶ singleCombinators p ⟶ sorted (AllowPortFromTo a b c # p) l ⟶ {a, b} ≠ firstList p ⟶ AllowPortFromTo u v w ∈ set p ⟶ {a, b} ≠ {u, v}" apply (cases p, simp_all) apply (intro impI conjI) apply (hypsubst,simp_all) proof - fix aa::"('a, 'b) Combinators" fix list::"('a, 'b) Combinators list" assume 1 : "¬ member DenyAll aa ∧ noDenyAll list" and 2: "{a, b} ∈ set l " and 3 : "in_list aa l ∧ all_in_list list l" and 4: "singleCombinators (aa # list)" and 5 : "smaller (AllowPortFromTo a b c) aa l ∧ sorted (aa # list) l" and 6 : "{a, b} ≠ first_bothNet aa" and 7: "AllowPortFromTo u v w ∈ set list" have *: "¬ smaller (AllowPortFromTo u v w) (AllowPortFromTo a b c) l" apply (insert 1 2 3 4 5 6 7, rule_tac y = aa and z = list in notSmallerTrans) apply (simp_all del: smaller.simps) apply (rule smalleraux3a,simp_all del: smaller.simps) apply (case_tac aa, simp_all del: smaller.simps) apply (case_tac aa, simp_all del: smaller.simps) done have **: "smaller (AllowPortFromTo a b c) (AllowPortFromTo u v w) l" apply(insert 1 2 3 4 5 6 7) apply (case_tac aa, simp_all del: smaller.simps) apply (rule_tac y = aa in order_trans,simp_all del: smaller.simps) apply (subgoal_tac "in_list (AllowPortFromTo u v w) l", simp) apply (rule_tac p = list in in_set_in_list, simp) apply (case_tac aa, simp_all del: smaller.simps) apply (rule_tac p = list in sorted_is_smaller,simp_all del: smaller.simps) apply (subgoal_tac "in_list (AllowPortFromTo u v w) l", simp) apply (rule_tac p = list in in_set_in_list, simp, simp) apply (rule_tac y = aa in order_trans,simp_all del: smaller.simps) apply (subgoal_tac "in_list (AllowPortFromTo u v w) l", simp) using in_set_in_list apply blast by (metis all_in_list.simps(2) bothNet.simps(3) in_list.simps(3) singleCombinators.simps(5) sorted_ConsA) show "{a, b} ≠ {u, v}" by (insert * **, simp_all split: if_splits) qed lemma NetsCollectedSorted[rule_format]: "noDenyAll1 p ⟶ all_in_list p l ⟶ singleCombinators p ⟶ sorted p l ⟶ NetsCollected p" apply (induct p) apply simp apply (intro impI,drule mp,erule noDA1C,drule mp,simp) apply (drule mp,erule singleCombinatorsConc) apply (drule mp,erule sortedConc) proof - fix a::" ('a, 'b) Combinators" fix p:: " ('a, 'b) Combinators list" assume 1: "noDenyAll1 (a # p)" and 2:"all_in_list (a # p) l" and 3: "singleCombinators (a # p)" and 4: "sorted (a # p) l" and 5: "NetsCollected p" show "NetsCollected (a # p)" apply(insert 1 2 3 4 5, rule fl3) apply(simp, rename_tac "aa") proof (cases a) case DenyAll fix aa::"('a, 'b) Combinators" assume 6: "aa ∈ set p" show "first_bothNet a ≠ first_bothNet aa" apply(insert 1 2 3 4 5 6 ‹a = DenyAll›, simp_all) using fMTaux noDA by blast next case (DenyAllFromTo x21 x22) fix aa::"('a, 'b) Combinators" assume 6: "first_bothNet a ≠ firstList p" and 7 :"aa ∈ set p" show "first_bothNet a ≠ first_bothNet aa" apply(insert 1 2 3 4 5 6 7 ‹a = DenyAllFromTo x21 x22›) apply(case_tac aa, simp_all) apply (meson NCSaux1) apply (meson NCSaux2) using SCnotConc by auto[1] next case (AllowPortFromTo x31 x32 x33) fix aa::"('a, 'b) Combinators" assume 6: "first_bothNet a ≠ firstList p" and 7 :"aa ∈ set p" show "first_bothNet a ≠ first_bothNet aa" apply(insert 1 2 3 4 6 7 ‹a = AllowPortFromTo x31 x32 x33›) apply(case_tac aa, simp_all) apply (meson NCSaux3) apply (meson NCSaux4) using SCnotConc by auto next case (Conc x41 x42) fix aa::"('a, 'b) Combinators" show "first_bothNet a ≠ first_bothNet aa" by(insert 3 4 ‹a = x41 ⊕ x42›,simp) qed qed lemma NetsCollectedSort: "distinct p ⟹noDenyAll1 p ⟹ all_in_list p l ⟹ singleCombinators p ⟹ NetsCollected (sort p l)" apply (rule_tac l = l in NetsCollectedSorted,rule noDAsort, simp_all) apply (rule_tac b=p in all_in_listSubset) by (auto intro: sort_is_sorted) lemma fBNsep[rule_format]: "(∀a∈set z. {b,c} ≠ first_bothNet a) ⟶ (∀a∈set (separate z). {b,c} ≠ first_bothNet a)" apply (induct z rule: separate.induct, simp) by (rule impI, simp)+ lemma fBNsep1[rule_format]: " (∀a∈set z. first_bothNet x ≠ first_bothNet a) ⟶ (∀a∈set (separate z). first_bothNet x ≠ first_bothNet a)" apply (induct z rule: separate.induct, simp) by (rule impI, simp)+ lemma NetsCollectedSepauxa: "{b,c}≠firstList z ⟹ noDenyAll1 z ⟹ ∀a∈set z. {b,c}≠first_bothNet a ⟹ NetsCollected z ⟹ NetsCollected (separate z) ⟹ {b, c} ≠ firstList (separate z) ⟹ a ∈ set (separate z) ⟹ {b, c} ≠ first_bothNet a" by (rule fBNsep) simp_all lemma NetsCollectedSepaux: "first_bothNet (x::('a,'b)Combinators) ≠ first_bothNet y ⟹ ¬ member DenyAll y ∧ noDenyAll z ⟹ (∀a∈set z. first_bothNet x ≠ first_bothNet a) ∧ NetsCollected (y # z) ⟹ NetsCollected (separate (y # z)) ⟹ first_bothNet x ≠ firstList (separate (y # z)) ⟹ a ∈ set (separate (y # z)) ⟹ first_bothNet (x::('a,'b)Combinators) ≠ first_bothNet (a::('a,'b)Combinators)" by (rule fBNsep1) auto lemma NetsCollectedSep[rule_format]: "noDenyAll1 p ⟶ NetsCollected p ⟶ NetsCollected (separate p)" proof (induct p rule: separate.induct, simp_all, goal_cases) fix x::"('a, 'b) Combinators list" case 1 then show ?case by (metis fMTaux noDA noDA1eq noDAsep) next fix v va y fix z::"('a, 'b) Combinators list" case 2 then show ?case apply (intro conjI impI, simp) apply (metis NetsCollectedSepaux fl3 noDA1eq noDenyAll.simps(1)) by (metis noDA1eq noDenyAll.simps(1)) next fix v va vb y fix z::"('a, 'b) Combinators list" case 3 then show ?case apply (intro conjI impI) apply (metis NetsCollectedSepaux fl3 noDA1eq noDenyAll.simps(1)) by (metis noDA1eq noDenyAll.simps(1)) next fix v va y fix z::"('a, 'b) Combinators list" case 4 then show ?case by (metis NetsCollectedSepaux fl3 noDA1eq noDenyAll.simps(1)) qed lemma OTNaux: "onlyTwoNets a ⟹ ¬ member DenyAll a ⟹ (x,y) ∈ sdnets a ⟹ (x = first_srcNet a ∧ y = first_destNet a) ∨ (x = first_destNet a ∧ y = first_srcNet a)" apply (case_tac "(x = first_srcNet a ∧ y = first_destNet a)",simp_all add: onlyTwoNets_def) apply (case_tac "(∃aa b. sdnets a = {(aa, b)})", simp_all) apply (subgoal_tac "sdnets a = {(first_srcNet a,first_destNet a)}", simp_all) apply (metis singletonE first_isIn) apply (subgoal_tac"sdnets a = {(first_srcNet a,first_destNet a),(first_destNet a, first_srcNet a)}") by(auto intro!: sdnets2) lemma sdnets_charn: "onlyTwoNets a ⟹ ¬ member DenyAll a ⟹ sdnets a = {(first_srcNet a,first_destNet a)} ∨ sdnets a = {(first_srcNet a, first_destNet a),(first_destNet a, first_srcNet a)}" apply (case_tac "sdnets a = {(first_srcNet a, first_destNet a)}", simp_all add: onlyTwoNets_def) apply (case_tac "(∃aa b. sdnets a = {(aa, b)})", simp_all) apply (metis singletonE first_isIn) apply (subgoal_tac "sdnets a = {(first_srcNet a,first_destNet a),(first_destNet a,first_srcNet a)}") by( auto intro!: sdnets2) lemma first_bothNet_charn[rule_format]: "¬ member DenyAll a ⟶ first_bothNet a = {first_srcNet a, first_destNet a}" by (induct a) simp_all lemma sdnets_noteq: "onlyTwoNets a ⟹ onlyTwoNets aa ⟹ first_bothNet a ≠ first_bothNet aa ⟹ ¬ member DenyAll a ⟹ ¬ member DenyAll aa ⟹ sdnets a ≠ sdnets aa" apply (insert sdnets_charn [of a]) apply (insert sdnets_charn [of aa]) apply (insert first_bothNet_charn [of a]) apply (insert first_bothNet_charn [of aa]) by(metis OTNaux first_isIn insert_absorb2 insert_commute) lemma fbn_noteq: "onlyTwoNets a ⟹ onlyTwoNets aa ⟹ first_bothNet a ≠ first_bothNet aa ⟹ ¬ member DenyAll a ⟹ ¬ member DenyAll aa ⟹ allNetsDistinct [a, aa] ⟹ first_srcNet a ≠ first_srcNet aa ∨ first_srcNet a ≠ first_destNet aa ∨ first_destNet a ≠ first_srcNet aa ∨ first_destNet a ≠ first_destNet aa" apply (insert sdnets_charn [of a]) apply (insert sdnets_charn [of aa]) by (metis first_bothNet_charn) lemma NCisSD2aux: assumes 1: "onlyTwoNets a" and 2 : "onlyTwoNets aa" and 3 : "first_bothNet a ≠ first_bothNet aa" and 4: "¬ member DenyAll a" and 5: "¬ member DenyAll aa" and 6:" allNetsDistinct [a, aa]" shows "disjSD_2 a aa" apply (insert 1 2 3 4 5 6) apply (simp add: disjSD_2_def) apply (intro allI impI) apply (insert sdnets_charn [of a] sdnets_charn [of aa], simp) apply (insert sdnets_noteq [of a aa] fbn_noteq [of a aa], simp) apply (simp add: allNetsDistinct_def twoNetsDistinct_def) proof - fix ab b c d assume 7: "∀ab b. ab≠b ∧ ab∈set(net_list_aux[a,aa]) ∧ b∈set(net_list_aux [a,aa]) ⟶ netsDistinct ab b" and 8: "(ab, b) ∈ sdnets a ∧ (c, d) ∈ sdnets aa " and 9: "sdnets a = {(first_srcNet a, first_destNet a)} ∨ sdnets a = {(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} " and 10: "sdnets aa = {(first_srcNet aa, first_destNet aa)} ∨ sdnets aa = {(first_srcNet aa, first_destNet aa), (first_destNet aa, first_srcNet aa)}" and 11: "sdnets a ≠ sdnets aa " and 12: "first_destNet a = first_srcNet aa ⟶ first_srcNet a = first_destNet aa ⟶ first_destNet aa ≠ first_srcNet aa" show "(netsDistinct ab c ∨ netsDistinct b d) ∧ (netsDistinct ab d ∨ netsDistinct b c)" proof (rule conjI) show "netsDistinct ab c ∨ netsDistinct b d" apply(insert 7 8 9 10 11 12) apply (cases "sdnets a = {(first_srcNet a, first_destNet a)}") apply (cases "sdnets aa = {(first_srcNet aa, first_destNet aa)}", simp_all) apply (metis 4 5 firstInNeta firstInNet alternativelistconc2) apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(first_srcNet a) ≠ (first_srcNet aa)",simp_all) apply (metis 4 5 firstInNeta alternativelistconc2) apply (subgoal_tac "first_destNet a ≠ first_destNet aa") apply (metis 4 5 firstInNet alternativelistconc2) apply (metis 3 4 5 first_bothNetsd) apply (case_tac "(first_destNet aa) ≠ (first_srcNet a)",simp_all) apply (metis 4 5 firstInNeta firstInNet alternativelistconc2) apply (case_tac "first_destNet aa ≠ first_destNet a",simp_all) apply (subgoal_tac "first_srcNet aa ≠ first_destNet a") apply (metis 4 5 firstInNeta firstInNet alternativelistconc2) apply (metis 3 4 5 first_bothNetsd insert_commute) apply (metis 5 firstInNeta firstInNet alternativelistconc2) apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)", simp_all) apply (case_tac "(first_srcNet a) ≠ (first_srcNet aa)",simp_all) apply (metis 4 5 firstInNeta alternativelistconc2) apply (subgoal_tac "first_destNet a ≠ first_destNet aa") apply (metis 4 5 firstInNet alternativelistconc2) apply (metis 3 4 5 first_bothNetsd ) apply (case_tac "(first_destNet aa) ≠ (first_srcNet a)",simp_all) apply (metis 4 5 firstInNeta firstInNet alternativelistconc2) apply (case_tac "first_destNet aa ≠ first_destNet a", simp) apply (subgoal_tac "first_srcNet aa ≠ first_destNet a") apply (metis 4 5 firstInNeta firstInNet alternativelistconc2) apply (metis 3 4 5 first_bothNetsd insert_commute) apply (metis) proof - assume 14 : "(ab = first_srcNet a ∧ b = first_destNet a ∨ ab = first_destNet a ∧ b = first_srcNet a) ∧ (c, d) ∈ sdnets aa " and 15 : "sdnets a = {(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} " and 16 : "sdnets aa = {(first_srcNet aa, first_destNet aa)} ∨ sdnets aa = {(first_srcNet aa, first_destNet aa), (first_destNet aa, first_srcNet aa)} " and 17 : "{(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} ≠ sdnets aa " and 18 : "first_destNet a = first_srcNet aa ⟶ first_srcNet a = first_destNet aa ⟶ first_destNet aa ≠ first_srcNet aa " and 19 : "first_destNet a ≠ first_srcNet a" and 20 : "c = first_srcNet aa ⟶ d ≠ first_destNet aa" show " netsDistinct ab c ∨ netsDistinct b d" apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)",simp_all) apply (case_tac "c = first_srcNet aa", simp_all) apply (metis 2 5 14 20 OTNaux) apply (subgoal_tac "c = first_destNet aa", simp) apply (subgoal_tac "d = first_srcNet aa", simp) apply (case_tac "(first_srcNet a) ≠ (first_destNet aa)",simp_all) apply (metis 4 5 7 firstInNeta firstInNet alternativelistconc2) apply (subgoal_tac "first_destNet a ≠ first_srcNet aa") apply (metis 4 5 7 firstInNeta firstInNet alternativelistconc2) apply (metis 3 4 5 first_bothNetsd insert_commute) apply (metis 2 5 14 OTNaux) apply (metis 2 5 14 OTNaux) apply (case_tac "c = first_srcNet aa", simp_all) apply (metis 2 5 14 20 OTNaux) apply (subgoal_tac "c = first_destNet aa", simp) apply (subgoal_tac "d = first_srcNet aa", simp) apply (case_tac "(first_destNet a) ≠ (first_destNet aa)",simp_all) apply (metis 4 5 7 14 firstInNet alternativelistconc2) apply (subgoal_tac "first_srcNet a ≠ first_srcNet aa") apply (metis 4 5 7 14 firstInNeta alternativelistconc2) apply (metis 3 4 5 first_bothNetsd insert_commute) apply (metis 2 5 14 OTNaux) apply (metis 2 5 14 OTNaux) done qed next show "netsDistinct ab d ∨ netsDistinct b c" apply (insert 1 2 3 4 5 6 7 8 9 10 11 12) apply (cases "sdnets a = {(first_srcNet a, first_destNet a)}") apply (cases "sdnets aa = {(first_srcNet aa, first_destNet aa)}", simp_all) apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(first_srcNet a) ≠ (first_destNet aa)", simp_all) apply (metis firstInNeta firstInNet alternativelistconc2) apply (subgoal_tac "first_destNet a ≠ first_srcNet aa") apply (metis firstInNeta firstInNet alternativelistconc2) apply (metis first_bothNetsd insert_commute) apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)", simp_all) apply (case_tac "(first_destNet a) ≠ (first_srcNet aa)",simp_all) apply (metis firstInNeta firstInNet alternativelistconc2) apply (subgoal_tac "first_srcNet a ≠ first_destNet aa") apply (metis firstInNeta firstInNet alternativelistconc2) apply (metis first_bothNetsd insert_commute) apply (case_tac "(first_srcNet aa) ≠ (first_srcNet a)",simp_all) apply (metis firstInNeta alternativelistconc2) apply (case_tac "first_destNet aa ≠ first_destNet a",simp_all) apply (metis firstInNet alternativelistconc2) apply (metis first_bothNetsd) proof - assume 13:" ∀ab b. ab ≠ b ∧ ab∈set(net_list_aux[a,aa]) ∧ b ∈ set(net_list_aux[a,aa]) ⟶ netsDistinct ab b " and 14 : "(ab = first_srcNet a ∧ b = first_destNet a ∨ ab = first_destNet a ∧ b = first_srcNet a) ∧ (c, d) ∈ sdnets aa " and 15 : " sdnets a = {(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} " and 16 : " sdnets aa = {(first_srcNet aa, first_destNet aa)} ∨ sdnets aa = {(first_srcNet aa, first_destNet aa), (first_destNet aa, first_srcNet aa)} " and 17 : " {(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} ≠ sdnets aa " show "first_destNet a ≠ first_srcNet a ⟹ netsDistinct ab d ∨ netsDistinct b c" apply (insert 1 2 3 4 5 6 13 14 15 16 17) apply (cases "sdnets aa = {(first_srcNet aa, first_destNet aa)}", simp_all) apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)", simp_all) apply (case_tac "(first_destNet a) ≠ (first_srcNet aa)",simp_all) apply (metis firstInNeta firstInNet alternativelistconc2) apply (subgoal_tac "first_srcNet a ≠ first_destNet aa") apply (metis firstInNeta firstInNet alternativelistconc2) apply (metis first_bothNetsd insert_commute) apply (case_tac "(first_srcNet aa) ≠ (first_srcNet a)",simp_all) apply (metis firstInNeta alternativelistconc2) apply (case_tac "first_destNet aa ≠ first_destNet a",simp_all) apply (metis firstInNet alternativelistconc2) apply (metis first_bothNetsd) proof - assume 20: "{(first_srcNet a, first_destNet a), (first_destNet a, first_srcNet a)} ≠ {(first_srcNet aa, first_destNet aa), (first_destNet aa, first_srcNet aa)}" and 21: "first_destNet a ≠ first_srcNet a" show "netsDistinct ab d ∨ netsDistinct b c" apply (case_tac "(c = first_srcNet aa ∧ d = first_destNet aa)", simp_all) apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)", simp_all) apply (case_tac "(first_destNet a) ≠ (first_srcNet aa)", simp_all) apply (metis 4 5 7 firstInNeta firstInNet alternativelistconc2) apply (subgoal_tac "first_srcNet a ≠ first_destNet aa") apply (metis 4 5 7 firstInNeta firstInNet alternativelistconc2) apply (metis 20 insert_commute) apply (case_tac "(first_srcNet aa) ≠ (first_srcNet a)", simp_all) apply (metis 4 5 13 14 firstInNeta alternativelistconc2) apply (case_tac "first_destNet aa ≠ first_destNet a", simp_all) apply (metis 4 5 13 14 firstInNet alternativelistconc2) apply (case_tac "(ab = first_srcNet a ∧ b = first_destNet a)", simp_all) apply (case_tac "(first_destNet a) ≠ (first_srcNet aa)", simp_all) apply (metis 20) apply (subgoal_tac "first_srcNet a ≠ first_srcNet aa") apply (metis 20) apply (metis 21) apply (case_tac "(first_srcNet aa) ≠ (first_destNet a)") apply (metis (no_types, lifting) 2 3 4 5 7 14 OTNaux firstInNet firstInNeta first_bothNetsd isInAlternativeList) by (metis 2 4 5 7 20 14 OTNaux doubleton_eq_iff firstInNet firstInNeta isInAlternativeList) qed qed qed qed lemma ANDaux3[rule_format]: "y ∈ set xs ⟶ a ∈ set (net_list_aux [y]) ⟶ a ∈ set (net_list_aux xs)" by (induct xs) (simp_all add: isInAlternativeList) lemma ANDaux2: "allNetsDistinct (x # xs) ⟹ y ∈ set xs ⟹ allNetsDistinct [x,y]" apply (simp add: allNetsDistinct_def) by (meson ANDaux3 isInAlternativeList netlistaux) lemma NCisSD2[rule_format]: "¬ member DenyAll a ⟹ OnlyTwoNets (a#p) ⟹ NetsCollected2 (a # p) ⟹ NetsCollected (a#p) ⟹ noDenyAll ( p) ⟹ allNetsDistinct (a # p) ⟹ s ∈ set p ⟹ disjSD_2 a s" by (metis ANDaux2 FWNormalisationCore.member.simps(2) NCisSD2aux NetsCollected.simps(1) NetsCollected2.simps(1) OTNConc OTNoTN empty_iff empty_set list.set_intros(1) noDA) lemma separatedNC[rule_format]: "OnlyTwoNets p ⟶ NetsCollected2 p ⟶ NetsCollected p ⟶ noDenyAll1 p ⟶ allNetsDistinct p ⟶ separated p" proof (induct p, simp_all, rename_tac a b, case_tac "a = DenyAll", simp_all, goal_cases) fix a fix p::"('a set set, 'b) Combinators list"