79 val args = map hol_term_to_fol_FO tms |
79 val args = map hol_term_to_fol_FO tms |
80 in Metis.Term.Fn (c, tyargs @ args) end |
80 in Metis.Term.Fn (c, tyargs @ args) end |
81 | (ResHolClause.CombVar(v,_), []) => Metis.Term.Var v |
81 | (ResHolClause.CombVar(v,_), []) => Metis.Term.Var v |
82 | _ => error "hol_term_to_fol_FO"; |
82 | _ => error "hol_term_to_fol_FO"; |
83 |
83 |
84 fun hol_term_to_fol_HO (ResHolClause.CombVar(a, ty)) = Metis.Term.Var a |
84 fun hol_term_to_fol_HO (ResHolClause.CombVar (a, _)) = Metis.Term.Var a |
85 | hol_term_to_fol_HO (ResHolClause.CombConst(a, ty, tylist)) = |
85 | hol_term_to_fol_HO (ResHolClause.CombConst (a, _, tylist)) = |
86 Metis.Term.Fn(fn_isa_to_met a, map hol_type_to_fol tylist) |
86 Metis.Term.Fn (fn_isa_to_met a, map hol_type_to_fol tylist) |
87 | hol_term_to_fol_HO (ResHolClause.CombApp(tm1,tm2)) = |
87 | hol_term_to_fol_HO (ResHolClause.CombApp (tm1, tm2)) = |
88 Metis.Term.Fn(".", map hol_term_to_fol_HO [tm1,tm2]); |
88 Metis.Term.Fn (".", map hol_term_to_fol_HO [tm1, tm2]); |
89 |
89 |
90 (*The fully-typed translation, to avoid type errors*) |
90 (*The fully-typed translation, to avoid type errors*) |
91 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]); |
91 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]); |
92 |
92 |
93 fun hol_term_to_fol_FT (ResHolClause.CombVar(a, ty)) = |
93 fun hol_term_to_fol_FT (ResHolClause.CombVar(a, ty)) = |
120 |
120 |
121 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*) |
121 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*) |
122 fun metis_of_typeLit pos (ResClause.LTVar (s,x)) = metis_lit pos s [Metis.Term.Var x] |
122 fun metis_of_typeLit pos (ResClause.LTVar (s,x)) = metis_lit pos s [Metis.Term.Var x] |
123 | metis_of_typeLit pos (ResClause.LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])]; |
123 | metis_of_typeLit pos (ResClause.LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])]; |
124 |
124 |
125 fun default_sort ctxt (TVar _) = false |
125 fun default_sort _ (TVar _) = false |
126 | default_sort ctxt (TFree(x,s)) = (s = Option.getOpt (Variable.def_sort ctxt (x,~1), [])); |
126 | default_sort ctxt (TFree (x, s)) = (s = Option.getOpt (Variable.def_sort ctxt (x, ~1), [])); |
127 |
127 |
128 fun metis_of_tfree tf = |
128 fun metis_of_tfree tf = |
129 Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_typeLit true tf)); |
129 Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_typeLit true tf)); |
130 |
130 |
131 fun hol_thm_to_fol is_conjecture ctxt mode th = |
131 fun hol_thm_to_fol is_conjecture ctxt mode th = |
174 fun terms_of [] = [] |
174 fun terms_of [] = [] |
175 | terms_of (Term t :: tts) = t :: terms_of tts |
175 | terms_of (Term t :: tts) = t :: terms_of tts |
176 | terms_of (Type _ :: tts) = terms_of tts; |
176 | terms_of (Type _ :: tts) = terms_of tts; |
177 |
177 |
178 fun types_of [] = [] |
178 fun types_of [] = [] |
179 | types_of (Term (Term.Var((a,idx), T)) :: tts) = |
179 | types_of (Term (Term.Var ((a,idx), _)) :: tts) = |
180 if String.isPrefix "_" a then |
180 if String.isPrefix "_" a then |
181 (*Variable generated by Metis, which might have been a type variable.*) |
181 (*Variable generated by Metis, which might have been a type variable.*) |
182 TVar(("'" ^ a, idx), HOLogic.typeS) :: types_of tts |
182 TVar (("'" ^ a, idx), HOLogic.typeS) :: types_of tts |
183 else types_of tts |
183 else types_of tts |
184 | types_of (Term _ :: tts) = types_of tts |
184 | types_of (Term _ :: tts) = types_of tts |
185 | types_of (Type T :: tts) = T :: types_of tts; |
185 | types_of (Type T :: tts) = T :: types_of tts; |
186 |
186 |
187 fun apply_list rator nargs rands = |
187 fun apply_list rator nargs rands = |
279 in case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected" end; |
279 in case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected" end; |
280 |
280 |
281 (*Maps fully-typed metis terms to isabelle terms*) |
281 (*Maps fully-typed metis terms to isabelle terms*) |
282 fun fol_term_to_hol_FT ctxt fol_tm = |
282 fun fol_term_to_hol_FT ctxt fol_tm = |
283 let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm) |
283 let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm) |
284 fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, ty])) = |
284 fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) = |
285 (case Recon.strip_prefix ResClause.schematic_var_prefix v of |
285 (case Recon.strip_prefix ResClause.schematic_var_prefix v of |
286 SOME w => mk_var(w, dummyT) |
286 SOME w => mk_var(w, dummyT) |
287 | NONE => mk_var(v, dummyT)) |
287 | NONE => mk_var(v, dummyT)) |
288 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), ty])) = |
288 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) = |
289 Const ("op =", HOLogic.typeT) |
289 Const ("op =", HOLogic.typeT) |
290 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) = |
290 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) = |
291 (case Recon.strip_prefix ResClause.const_prefix x of |
291 (case Recon.strip_prefix ResClause.const_prefix x of |
292 SOME c => Const (Recon.invert_const c, dummyT) |
292 SOME c => Const (Recon.invert_const c, dummyT) |
293 | NONE => (*Not a constant. Is it a fixed variable??*) |
293 | NONE => (*Not a constant. Is it a fixed variable??*) |
449 val i_t = singleton (fol_terms_to_hol ctxt mode) t |
448 val i_t = singleton (fol_terms_to_hol ctxt mode) t |
450 val _ = trace_msg (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
449 val _ = trace_msg (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
451 val c_t = cterm_incr_types thy refl_idx i_t |
450 val c_t = cterm_incr_types thy refl_idx i_t |
452 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
451 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
453 |
452 |
454 fun get_ty_arg_size thy (Const("op =",_)) = 0 (*equality has no type arguments*) |
453 fun get_ty_arg_size _ (Const ("op =", _)) = 0 (*equality has no type arguments*) |
455 | get_ty_arg_size thy (Const(c,_)) = (Recon.num_typargs thy c handle TYPE _ => 0) |
454 | get_ty_arg_size thy (Const (c, _)) = (Recon.num_typargs thy c handle TYPE _ => 0) |
456 | get_ty_arg_size thy _ = 0; |
455 | get_ty_arg_size _ _ = 0; |
457 |
456 |
458 (* INFERENCE RULE: EQUALITY *) |
457 (* INFERENCE RULE: EQUALITY *) |
459 fun equality_inf ctxt mode thpairs (pos,atm) fp fr = |
458 fun equality_inf ctxt mode (pos, atm) fp fr = |
460 let val thy = ProofContext.theory_of ctxt |
459 let val thy = ProofContext.theory_of ctxt |
461 val m_tm = Metis.Term.Fn atm |
460 val m_tm = Metis.Term.Fn atm |
462 val [i_atm,i_tm] = fol_terms_to_hol ctxt mode [m_tm, fr] |
461 val [i_atm,i_tm] = fol_terms_to_hol ctxt mode [m_tm, fr] |
463 val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos) |
462 val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos) |
464 fun replace_item_list lx 0 (l::ls) = lx::ls |
463 fun replace_item_list lx 0 (_::ls) = lx::ls |
465 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
464 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
466 fun path_finder_FO tm [] = (tm, Term.Bound 0) |
465 fun path_finder_FO tm [] = (tm, Term.Bound 0) |
467 | path_finder_FO tm (p::ps) = |
466 | path_finder_FO tm (p::ps) = |
468 let val (tm1,args) = Term.strip_comb tm |
467 let val (tm1,args) = Term.strip_comb tm |
469 val adjustment = get_ty_arg_size thy tm1 |
468 val adjustment = get_ty_arg_size thy tm1 |
477 in |
476 in |
478 (r, list_comb (tm1, replace_item_list t p' args)) |
477 (r, list_comb (tm1, replace_item_list t p' args)) |
479 end |
478 end |
480 fun path_finder_HO tm [] = (tm, Term.Bound 0) |
479 fun path_finder_HO tm [] = (tm, Term.Bound 0) |
481 | path_finder_HO (t$u) (0::ps) = (fn(x,y) => (x, y$u)) (path_finder_HO t ps) |
480 | path_finder_HO (t$u) (0::ps) = (fn(x,y) => (x, y$u)) (path_finder_HO t ps) |
482 | path_finder_HO (t$u) (p::ps) = (fn(x,y) => (x, t$y)) (path_finder_HO u ps) |
481 | path_finder_HO (t$u) (_::ps) = (fn(x,y) => (x, t$y)) (path_finder_HO u ps) |
483 fun path_finder_FT tm [] _ = (tm, Term.Bound 0) |
482 fun path_finder_FT tm [] _ = (tm, Term.Bound 0) |
484 | path_finder_FT tm (0::ps) (Metis.Term.Fn ("ti", [t1,t2])) = |
483 | path_finder_FT tm (0::ps) (Metis.Term.Fn ("ti", [t1, _])) = |
485 path_finder_FT tm ps t1 |
484 path_finder_FT tm ps t1 |
486 | path_finder_FT (t$u) (0::ps) (Metis.Term.Fn (".", [t1,t2])) = |
485 | path_finder_FT (t$u) (0::ps) (Metis.Term.Fn (".", [t1, _])) = |
487 (fn(x,y) => (x, y$u)) (path_finder_FT t ps t1) |
486 (fn(x,y) => (x, y$u)) (path_finder_FT t ps t1) |
488 | path_finder_FT (t$u) (1::ps) (Metis.Term.Fn (".", [t1,t2])) = |
487 | path_finder_FT (t$u) (1::ps) (Metis.Term.Fn (".", [_, t2])) = |
489 (fn(x,y) => (x, t$y)) (path_finder_FT u ps t2) |
488 (fn(x,y) => (x, t$y)) (path_finder_FT u ps t2) |
490 | path_finder_FT tm ps t = error ("equality_inf, path_finder_FT: path = " ^ |
489 | path_finder_FT tm ps t = error ("equality_inf, path_finder_FT: path = " ^ |
491 space_implode " " (map Int.toString ps) ^ |
490 space_implode " " (map Int.toString ps) ^ |
492 " isa-term: " ^ Syntax.string_of_term ctxt tm ^ |
491 " isa-term: " ^ Syntax.string_of_term ctxt tm ^ |
493 " fol-term: " ^ Metis.Term.toString t) |
492 " fol-term: " ^ Metis.Term.toString t) |
494 fun path_finder FO tm ps _ = path_finder_FO tm ps |
493 fun path_finder FO tm ps _ = path_finder_FO tm ps |
495 | path_finder HO (tm as Const("op =",_) $ _ $ _) (p::ps) _ = |
494 | path_finder HO (tm as Const("op =",_) $ _ $ _) (p::ps) _ = |
496 (*equality: not curried, as other predicates are*) |
495 (*equality: not curried, as other predicates are*) |
497 if p=0 then path_finder_HO tm (0::1::ps) (*select first operand*) |
496 if p=0 then path_finder_HO tm (0::1::ps) (*select first operand*) |
498 else path_finder_HO tm (p::ps) (*1 selects second operand*) |
497 else path_finder_HO tm (p::ps) (*1 selects second operand*) |
499 | path_finder HO tm (p::ps) (Metis.Term.Fn ("{}", [t1])) = |
498 | path_finder HO tm (_ :: ps) (Metis.Term.Fn ("{}", [_])) = |
500 path_finder_HO tm ps (*if not equality, ignore head to skip hBOOL*) |
499 path_finder_HO tm ps (*if not equality, ignore head to skip hBOOL*) |
501 | path_finder FT (tm as Const("op =",_) $ _ $ _) (p::ps) |
500 | path_finder FT (tm as Const("op =",_) $ _ $ _) (p::ps) |
502 (Metis.Term.Fn ("=", [t1,t2])) = |
501 (Metis.Term.Fn ("=", [t1,t2])) = |
503 (*equality: not curried, as other predicates are*) |
502 (*equality: not curried, as other predicates are*) |
504 if p=0 then path_finder_FT tm (0::1::ps) |
503 if p=0 then path_finder_FT tm (0::1::ps) |
505 (Metis.Term.Fn (".", [Metis.Term.Fn (".", [metis_eq,t1]), t2])) |
504 (Metis.Term.Fn (".", [Metis.Term.Fn (".", [metis_eq,t1]), t2])) |
506 (*select first operand*) |
505 (*select first operand*) |
507 else path_finder_FT tm (p::ps) |
506 else path_finder_FT tm (p::ps) |
508 (Metis.Term.Fn (".", [metis_eq,t2])) |
507 (Metis.Term.Fn (".", [metis_eq,t2])) |
509 (*1 selects second operand*) |
508 (*1 selects second operand*) |
510 | path_finder FT tm (p::ps) (Metis.Term.Fn ("{}", [t1])) = path_finder_FT tm ps t1 |
509 | path_finder FT tm (_ :: ps) (Metis.Term.Fn ("{}", [t1])) = path_finder_FT tm ps t1 |
511 (*if not equality, ignore head to skip the hBOOL predicate*) |
510 (*if not equality, ignore head to skip the hBOOL predicate*) |
512 | path_finder FT tm ps t = path_finder_FT tm ps t (*really an error case!*) |
511 | path_finder FT tm ps t = path_finder_FT tm ps t (*really an error case!*) |
513 fun path_finder_lit ((nt as Term.Const ("Not", _)) $ tm_a) idx = |
512 fun path_finder_lit ((nt as Term.Const ("Not", _)) $ tm_a) idx = |
514 let val (tm, tm_rslt) = path_finder mode tm_a idx m_tm |
513 let val (tm, tm_rslt) = path_finder mode tm_a idx m_tm |
515 in (tm, nt $ tm_rslt) end |
514 in (tm, nt $ tm_rslt) end |
526 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
525 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
527 in cterm_instantiate eq_terms subst' end; |
526 in cterm_instantiate eq_terms subst' end; |
528 |
527 |
529 val factor = Seq.hd o distinct_subgoals_tac; |
528 val factor = Seq.hd o distinct_subgoals_tac; |
530 |
529 |
531 fun step ctxt mode thpairs (fol_th, Metis.Proof.Axiom _) = |
530 fun step _ _ thpairs (fol_th, Metis.Proof.Axiom _) = factor (axiom_inf thpairs fol_th) |
532 factor (axiom_inf ctxt thpairs fol_th) |
531 | step ctxt mode _ (_, Metis.Proof.Assume f_atm) = assume_inf ctxt mode f_atm |
533 | step ctxt mode thpairs (_, Metis.Proof.Assume f_atm) = |
532 | step ctxt mode thpairs (_, Metis.Proof.Subst (f_subst, f_th1)) = |
534 assume_inf ctxt mode f_atm |
|
535 | step ctxt mode thpairs (_, Metis.Proof.Subst(f_subst, f_th1)) = |
|
536 factor (inst_inf ctxt mode thpairs f_subst f_th1) |
533 factor (inst_inf ctxt mode thpairs f_subst f_th1) |
537 | step ctxt mode thpairs (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) = |
534 | step ctxt mode thpairs (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) = |
538 factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2) |
535 factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2) |
539 | step ctxt mode thpairs (_, Metis.Proof.Refl f_tm) = |
536 | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm |
540 refl_inf ctxt mode f_tm |
537 | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) = |
541 | step ctxt mode thpairs (_, Metis.Proof.Equality(f_lit, f_p, f_r)) = |
538 equality_inf ctxt mode f_lit f_p f_r; |
542 equality_inf ctxt mode thpairs f_lit f_p f_r; |
539 |
543 |
540 fun real_literal (_, (c, _)) = not (String.isPrefix ResClause.class_prefix c); |
544 fun real_literal (b, (c, _)) = not (String.isPrefix ResClause.class_prefix c); |
541 |
545 |
542 fun translate _ _ thpairs [] = thpairs |
546 fun translate mode _ thpairs [] = thpairs |
|
547 | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) = |
543 | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) = |
548 let val _ = trace_msg (fn () => "=============================================") |
544 let val _ = trace_msg (fn () => "=============================================") |
549 val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th) |
545 val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th) |
550 val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf) |
546 val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf) |
551 val th = Meson.flexflex_first_order (step ctxt mode thpairs (fol_th, inf)) |
547 val th = Meson.flexflex_first_order (step ctxt mode thpairs (fol_th, inf)) |
552 val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
548 val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
553 val _ = trace_msg (fn () => "=============================================") |
549 val _ = trace_msg (fn () => "=============================================") |
554 val n_metis_lits = length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th))) |
550 val n_metis_lits = |
|
551 length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th))) |
555 in |
552 in |
556 if nprems_of th = n_metis_lits then () |
553 if nprems_of th = n_metis_lits then () |
557 else error "Metis: proof reconstruction has gone wrong"; |
554 else error "Metis: proof reconstruction has gone wrong"; |
558 translate mode ctxt ((fol_th, th) :: thpairs) infpairs |
555 translate mode ctxt ((fol_th, th) :: thpairs) infpairs |
559 end; |
556 end; |
560 |
557 |
561 (*Determining which axiom clauses are actually used*) |
558 (*Determining which axiom clauses are actually used*) |
562 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th) |
559 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th) |
563 | used_axioms axioms _ = NONE; |
560 | used_axioms _ _ = NONE; |
564 |
561 |
565 (* ------------------------------------------------------------------------- *) |
562 (* ------------------------------------------------------------------------- *) |
566 (* Translation of HO Clauses *) |
563 (* Translation of HO Clauses *) |
567 (* ------------------------------------------------------------------------- *) |
564 (* ------------------------------------------------------------------------- *) |
568 |
565 |
593 |
589 |
594 type logic_map = |
590 type logic_map = |
595 {axioms : (Metis.Thm.thm * Thm.thm) list, |
591 {axioms : (Metis.Thm.thm * Thm.thm) list, |
596 tfrees : ResClause.type_literal list}; |
592 tfrees : ResClause.type_literal list}; |
597 |
593 |
598 fun const_in_metis c (pol,(pred,tm_list)) = |
594 fun const_in_metis c (pred, tm_list) = |
599 let |
595 let |
600 fun in_mterm (Metis.Term.Var nm) = false |
596 fun in_mterm (Metis.Term.Var _) = false |
601 | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list |
597 | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list |
602 | in_mterm (Metis.Term.Fn (nm, tm_list)) = c=nm orelse exists in_mterm tm_list |
598 | in_mterm (Metis.Term.Fn (nm, tm_list)) = c=nm orelse exists in_mterm tm_list |
603 in c=pred orelse exists in_mterm tm_list end; |
599 in c = pred orelse exists in_mterm tm_list end; |
604 |
600 |
605 (*Extract TFree constraints from context to include as conjecture clauses*) |
601 (*Extract TFree constraints from context to include as conjecture clauses*) |
606 fun init_tfrees ctxt = |
602 fun init_tfrees ctxt = |
607 let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts |
603 let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts |
608 in ResClause.add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end; |
604 in ResClause.add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end; |
639 end; |
635 end; |
640 val lmap0 = List.foldl (add_thm true) |
636 val lmap0 = List.foldl (add_thm true) |
641 {axioms = [], tfrees = init_tfrees ctxt} cls |
637 {axioms = [], tfrees = init_tfrees ctxt} cls |
642 val lmap = List.foldl (add_thm false) (add_tfrees lmap0) ths |
638 val lmap = List.foldl (add_thm false) (add_tfrees lmap0) ths |
643 val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap) |
639 val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap) |
644 fun used c = exists (Metis.LiteralSet.exists (const_in_metis c)) clause_lists |
640 fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists |
645 (*Now check for the existence of certain combinators*) |
641 (*Now check for the existence of certain combinators*) |
646 val thI = if used "c_COMBI" then [comb_I] else [] |
642 val thI = if used "c_COMBI" then [comb_I] else [] |
647 val thK = if used "c_COMBK" then [comb_K] else [] |
643 val thK = if used "c_COMBK" then [comb_K] else [] |
648 val thB = if used "c_COMBB" then [comb_B] else [] |
644 val thB = if used "c_COMBB" then [comb_B] else [] |
649 val thC = if used "c_COMBC" then [comb_C] else [] |
645 val thC = if used "c_COMBC" then [comb_C] else [] |