| author | nipkow | 
| Thu, 01 Apr 2010 09:31:58 +0200 | |
| changeset 36070 | d80e5d3c8fe1 | 
| parent 35821 | ee34f03a7d26 | 
| child 37744 | 3daaf23b9ab4 | 
| permissions | -rw-r--r-- | 
| 35648 | 1 | (* Author: Amine Chaieb, University of Cambridge, 2009 | 
| 2 | Jeremy Avigad, Carnegie Mellon University | |
| 3 | Florian Haftmann, TU Muenchen | |
| 4 | ||
| 5 | Simple transfer principle on theorems. | |
| 31706 | 6 | *) | 
| 7 | ||
| 32557 
3cfe4c13aa6e
plain structure name; signature constraint; shorter lines
 haftmann parents: 
32476diff
changeset | 8 | signature TRANSFER = | 
| 31706 | 9 | sig | 
| 35648 | 10 | datatype selection = Direction of term * term | Hints of string list | Prop | 
| 35674 | 11 | val transfer: Context.generic -> selection -> string list -> thm -> thm list | 
| 31706 | 12 | type entry | 
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 13 | val add: thm -> bool -> entry -> Context.generic -> Context.generic | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 14 | val del: thm -> entry -> Context.generic -> Context.generic | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 15 | val drop: thm -> Context.generic -> Context.generic | 
| 31706 | 16 | val setup: theory -> theory | 
| 17 | end; | |
| 18 | ||
| 32557 
3cfe4c13aa6e
plain structure name; signature constraint; shorter lines
 haftmann parents: 
32476diff
changeset | 19 | structure Transfer : TRANSFER = | 
| 31706 | 20 | struct | 
| 32557 
3cfe4c13aa6e
plain structure name; signature constraint; shorter lines
 haftmann parents: 
32476diff
changeset | 21 | |
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 22 | (* data administration *) | 
| 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 23 | |
| 35647 | 24 | val direction_of = Thm.dest_binop o Thm.dest_arg o cprop_of; | 
| 25 | ||
| 35821 | 26 | val transfer_morphism_key = Drule.strip_imp_concl (Thm.cprop_of @{thm transfer_morphismI});
 | 
| 27 | ||
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 28 | fun check_morphism_key ctxt key = | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 29 | let | 
| 35821 | 30 | val _ = Thm.match (transfer_morphism_key, Thm.cprop_of key) | 
| 31 |       handle Pattern.MATCH => error ("Transfer: expected theorem of the form "
 | |
| 32 | ^ quote (Syntax.string_of_term ctxt (Thm.term_of transfer_morphism_key))); | |
| 35647 | 33 | in direction_of key end; | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 34 | |
| 35674 | 35 | type entry = { inj : thm list, embed : thm list, return : thm list, cong : thm list,
 | 
| 35675 | 36 | hints : string list }; | 
| 33321 | 37 | |
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 38 | val empty_entry = { inj = [], embed = [], return = [], cong = [], hints = [] };
 | 
| 35675 | 39 | fun merge_entry ({ inj = inj1, embed = embed1, return = return1, cong = cong1, hints = hints1 } : entry,
 | 
| 40 |   { inj = inj2, embed = embed2, return = return2, cong = cong2, hints = hints2 } : entry) =
 | |
| 35674 | 41 |     { inj = merge Thm.eq_thm (inj1, inj2), embed = merge Thm.eq_thm (embed1, embed2),
 | 
| 42 | return = merge Thm.eq_thm (return1, return2), cong = merge Thm.eq_thm (cong1, cong2), | |
| 35675 | 43 | hints = merge (op =) (hints1, hints2) }; | 
| 33321 | 44 | |
| 33519 | 45 | structure Data = Generic_Data | 
| 31706 | 46 | ( | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 47 | type T = (thm * entry) list; | 
| 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 48 | val empty = []; | 
| 35647 | 49 | val extend = I; | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 50 | val merge = AList.join Thm.eq_thm (K merge_entry); | 
| 31706 | 51 | ); | 
| 52 | ||
| 35647 | 53 | |
| 54 | (* data lookup *) | |
| 55 | ||
| 35708 | 56 | fun transfer_rules_of ({ inj, embed, return, cong, ... } : entry) =
 | 
| 35675 | 57 | (inj, embed, return, cong); | 
| 58 | ||
| 35647 | 59 | fun get_by_direction context (a, D) = | 
| 60 | let | |
| 61 | val ctxt = Context.proof_of context; | |
| 62 | val certify = Thm.cterm_of (Context.theory_of context); | |
| 63 | val a0 = certify a; | |
| 64 | val D0 = certify D; | |
| 65 | fun eq_direction ((a, D), thm') = | |
| 66 | let | |
| 67 | val (a', D') = direction_of thm'; | |
| 35674 | 68 | in a aconvc a' andalso D aconvc D' end; | 
| 69 | in case AList.lookup eq_direction (Data.get context) (a0, D0) of | |
| 35675 | 70 | SOME e => ((a0, D0), transfer_rules_of e) | 
| 35647 | 71 |     | NONE => error ("Transfer: no such instance: ("
 | 
| 72 | ^ Syntax.string_of_term ctxt a ^ ", " ^ Syntax.string_of_term ctxt D ^ ")") | |
| 73 | end; | |
| 31706 | 74 | |
| 35647 | 75 | fun get_by_hints context hints = | 
| 76 | let | |
| 77 | val insts = map_filter (fn (k, e) => if exists (member (op =) (#hints e)) hints | |
| 35675 | 78 | then SOME (direction_of k, transfer_rules_of e) else NONE) (Data.get context); | 
| 35647 | 79 |     val _ = if null insts then error ("Transfer: no such labels: " ^ commas (map quote hints)) else ();
 | 
| 80 | in insts end; | |
| 81 | ||
| 82 | fun splits P [] = [] | |
| 83 | | splits P (xs as (x :: _)) = | |
| 84 | let | |
| 85 | val (pss, qss) = List.partition (P x) xs; | |
| 86 | in if null pss then [qss] else if null qss then [pss] else pss :: splits P qss end; | |
| 31706 | 87 | |
| 35647 | 88 | fun get_by_prop context t = | 
| 89 | let | |
| 90 | val tys = map snd (Term.add_vars t []); | |
| 91 | val _ = if null tys then error "Transfer: unable to guess instance" else (); | |
| 92 | val tyss = splits (curry Type.could_unify) tys; | |
| 93 | val get_ty = typ_of o ctyp_of_term o fst o direction_of; | |
| 35675 | 94 | val insts = map_filter (fn tys => get_first (fn (k, e) => | 
| 35647 | 95 | if Type.could_unify (hd tys, range_type (get_ty k)) | 
| 35675 | 96 | then SOME (direction_of k, transfer_rules_of e) | 
| 35647 | 97 | else NONE) (Data.get context)) tyss; | 
| 98 | val _ = if null insts then | |
| 99 | error "Transfer: no instances, provide direction or hints explicitly" else (); | |
| 100 | in insts end; | |
| 31706 | 101 | |
| 102 | ||
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 103 | (* applying transfer data *) | 
| 31706 | 104 | |
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 105 | fun transfer_thm ((raw_a, raw_D), (inj, embed, return, cong)) leave ctxt1 thm = | 
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 106 | let | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 107 | (* identify morphism function *) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 108 | val ([a, D], ctxt2) = ctxt1 | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 109 | |> Variable.import true (map Drule.mk_term [raw_a, raw_D]) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 110 | |>> map Drule.dest_term o snd; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 111 |     val transform = Thm.capply @{cterm "Trueprop"} o Thm.capply D;
 | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 112 | val T = Thm.typ_of (Thm.ctyp_of_term a); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 113 | val (aT, bT) = (Term.range_type T, Term.domain_type T); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 114 | |
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 115 | (* determine variables to transfer *) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 116 | val ctxt3 = ctxt2 | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 117 | |> Variable.declare_thm thm | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 118 | |> Variable.declare_term (term_of a) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 119 | |> Variable.declare_term (term_of D); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 120 | val certify = Thm.cterm_of (ProofContext.theory_of ctxt3); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 121 | val vars = filter (fn ((v, _), T) => Type.could_unify (T, aT) andalso | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 122 | not (member (op =) leave v)) (Term.add_vars (Thm.prop_of thm) []); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 123 | val c_vars = map (certify o Var) vars; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 124 | val (vs', ctxt4) = Variable.variant_fixes (map (fst o fst) vars) ctxt3; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 125 | val c_vars' = map (certify o (fn v => Free (v, bT))) vs'; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 126 | val c_exprs' = map (Thm.capply a) c_vars'; | 
| 31706 | 127 | |
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 128 | (* transfer *) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 129 | val (hyps, ctxt5) = ctxt4 | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 130 | |> Assumption.add_assumes (map transform c_vars'); | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 131 | val simpset = Simplifier.context ctxt5 HOL_ss | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 132 | addsimps (inj @ embed @ return) addcongs cong; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 133 | val thm' = thm | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 134 | |> Drule.cterm_instantiate (c_vars ~~ c_exprs') | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 135 | |> fold_rev Thm.implies_intr (map cprop_of hyps) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 136 | |> Simplifier.asm_full_simplify simpset | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 137 | in singleton (Variable.export ctxt5 ctxt1) thm' end; | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 138 | |
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 139 | fun transfer_thm_multiple insts leave ctxt thm = | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 140 | map (fn inst => transfer_thm inst leave ctxt thm) insts; | 
| 31706 | 141 | |
| 35648 | 142 | datatype selection = Direction of term * term | Hints of string list | Prop; | 
| 35647 | 143 | |
| 35648 | 144 | fun insts_for context thm (Direction direction) = [get_by_direction context direction] | 
| 145 | | insts_for context thm (Hints hints) = get_by_hints context hints | |
| 146 | | insts_for context thm Prop = get_by_prop context (Thm.prop_of thm); | |
| 31706 | 147 | |
| 35648 | 148 | fun transfer context selection leave thm = | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 149 | transfer_thm_multiple (insts_for context thm selection) leave (Context.proof_of context) thm; | 
| 31706 | 150 | |
| 151 | ||
| 35647 | 152 | (* maintaining transfer data *) | 
| 31706 | 153 | |
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 154 | fun extend_entry ctxt (a, D) guess | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 155 |     { inj = inj1, embed = embed1, return = return1, cong = cong1, hints = hints1 }
 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 156 |     { inj = inj2, embed = embed2, return = return2, cong = cong2, hints = hints2 } =
 | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 157 | let | 
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 158 | fun add_del eq del add = union eq add #> subtract eq del; | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 159 | val guessed = if guess | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 160 | then map (fn thm => transfer_thm | 
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 161 | ((a, D), (if null inj1 then inj2 else inj1, [], [], cong1)) [] ctxt thm RS sym) embed1 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 162 | else []; | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 163 | in | 
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 164 |     { inj = union Thm.eq_thm inj1 inj2, embed = union Thm.eq_thm embed1 embed2,
 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 165 | return = union Thm.eq_thm guessed (union Thm.eq_thm return1 return2), | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 166 | cong = union Thm.eq_thm cong1 cong2, hints = union (op =) hints1 hints2 } | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 167 | end; | 
| 31706 | 168 | |
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 169 | fun diminish_entry | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 170 |     { inj = inj0, embed = embed0, return = return0, cong = cong0, hints = hints0 }
 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 171 |     { inj = inj2, embed = embed2, return = return2, cong = cong2, hints = hints2 } =
 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 172 |   { inj = subtract Thm.eq_thm inj0 inj2, embed = subtract Thm.eq_thm embed0 embed2,
 | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 173 | return = subtract Thm.eq_thm return0 return2, cong = subtract Thm.eq_thm cong0 cong2, | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 174 | hints = subtract (op =) hints0 hints2 }; | 
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 175 | |
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 176 | fun add key guess entry context = | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 177 | let | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 178 | val ctxt = Context.proof_of context; | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 179 | val a_D = check_morphism_key ctxt key; | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 180 | in | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 181 | context | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 182 | |> Data.map (AList.map_default Thm.eq_thm | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 183 | (key, empty_entry) (extend_entry ctxt a_D guess entry)) | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 184 | end; | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 185 | |
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 186 | fun del key entry = Data.map (AList.map_entry Thm.eq_thm key (diminish_entry entry)); | 
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 187 | |
| 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 188 | fun drop key = Data.map (AList.delete Thm.eq_thm key); | 
| 35647 | 189 | |
| 31706 | 190 | |
| 35638 
50655e2ebc85
dropped dead code; adhere more closely to standard coding conventions
 haftmann parents: 
33519diff
changeset | 191 | (* syntax *) | 
| 31706 | 192 | |
| 193 | local | |
| 194 | ||
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 195 | fun these scan = Scan.optional scan []; | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 196 | fun these_pair scan = Scan.optional scan ([], []); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 197 | |
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 198 | fun keyword k = Scan.lift (Args.$$$ k) >> K (); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 199 | fun keyword_colon k = Scan.lift (Args.$$$ k -- Args.colon) >> K (); | 
| 31706 | 200 | |
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 201 | val addN = "add"; | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 202 | val delN = "del"; | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 203 | val keyN = "key"; | 
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 204 | val modeN = "mode"; | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 205 | val automaticN = "automatic"; | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 206 | val manualN = "manual"; | 
| 35674 | 207 | val injN = "inj"; | 
| 208 | val embedN = "embed"; | |
| 209 | val returnN = "return"; | |
| 210 | val congN = "cong"; | |
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 211 | val labelsN = "labels"; | 
| 31706 | 212 | |
| 35674 | 213 | val leavingN = "leaving"; | 
| 214 | val directionN = "direction"; | |
| 215 | ||
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 216 | val any_keyword = keyword_colon addN || keyword_colon delN || keyword_colon keyN | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 217 | || keyword_colon modeN || keyword_colon injN || keyword_colon embedN || keyword_colon returnN | 
| 35674 | 218 | || keyword_colon congN || keyword_colon labelsN | 
| 219 | || keyword_colon leavingN || keyword_colon directionN; | |
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 220 | |
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 221 | val thms = Scan.repeat (Scan.unless any_keyword Attrib.multi_thm) >> flat; | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 222 | val names = Scan.repeat (Scan.unless any_keyword (Scan.lift Args.name)) | 
| 31706 | 223 | |
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 224 | val mode = keyword_colon modeN |-- ((Scan.lift (Args.$$$ manualN) >> K false) | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 225 | || (Scan.lift (Args.$$$ automaticN) >> K true)); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 226 | val inj = (keyword_colon injN |-- thms) -- these (keyword_colon delN |-- thms); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 227 | val embed = (keyword_colon embedN |-- thms) -- these (keyword_colon delN |-- thms); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 228 | val return = (keyword_colon returnN |-- thms) -- these (keyword_colon delN |-- thms); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 229 | val cong = (keyword_colon congN |-- thms) -- these (keyword_colon delN |-- thms); | 
| 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 230 | val labels = (keyword_colon labelsN |-- names) -- these (keyword_colon delN |-- names); | 
| 31706 | 231 | |
| 35675 | 232 | val entry_pair = these_pair inj -- these_pair embed | 
| 35648 | 233 | -- these_pair return -- these_pair cong -- these_pair labels | 
| 35675 | 234 | >> (fn (((((inja, injd), (embeda, embedd)), (returna, returnd)), (conga, congd)), | 
| 35674 | 235 | (hintsa, hintsd)) => | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 236 |       ({ inj = inja, embed = embeda, return = returna, cong = conga, hints = hintsa },
 | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 237 |         { inj = injd, embed = embedd, return = returnd, cong = congd, hints = hintsd }));
 | 
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 238 | |
| 35648 | 239 | val selection = (keyword_colon directionN |-- (Args.term -- Args.term) >> Direction) | 
| 240 | || these names >> (fn hints => if null hints then Prop else Hints hints); | |
| 35645 
74e4542d0a4a
transfer: avoid camel case, more standard coding conventions, misc tuning
 haftmann parents: 
35638diff
changeset | 241 | |
| 31706 | 242 | in | 
| 243 | ||
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 244 | val transfer_attribute = keyword delN >> K (Thm.declaration_attribute drop) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 245 | || keyword addN |-- Scan.optional mode true -- entry_pair | 
| 35676 
9fa8548d043d
data administration using canonical functorial operations
 haftmann parents: 
35675diff
changeset | 246 | >> (fn (guess, (entry_add, entry_del)) => Thm.declaration_attribute | 
| 35684 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 247 | (fn thm => add thm guess entry_add #> del thm entry_del)) | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 248 | || keyword_colon keyN |-- Attrib.thm | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 249 | >> (fn key => Thm.declaration_attribute | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 250 | (fn thm => add key false | 
| 
97b94dc975c7
clarified transfer code proper; more natural declaration of return rules
 haftmann parents: 
35676diff
changeset | 251 |         { inj = [], embed = [], return = [thm], cong = [], hints = [] }));
 | 
| 31706 | 252 | |
| 35648 | 253 | val transferred_attribute = selection -- these (keyword_colon leavingN |-- names) | 
| 35674 | 254 | >> (fn (selection, leave) => Thm.rule_attribute (fn context => | 
| 255 | Conjunction.intr_balanced o transfer context selection leave)); | |
| 31706 | 256 | |
| 257 | end; | |
| 258 | ||
| 259 | ||
| 260 | (* theory setup *) | |
| 261 | ||
| 262 | val setup = | |
| 35648 | 263 |   Attrib.setup @{binding transfer} transfer_attribute
 | 
| 31706 | 264 | "Installs transfer data" #> | 
| 35648 | 265 |   Attrib.setup @{binding transferred} transferred_attribute
 | 
| 31706 | 266 | "Transfers theorems"; | 
| 267 | ||
| 268 | end; |