src/Tools/Metis/src/Rule.sml
changeset 39353 7f11d833d65b
parent 23510 4521fead5609
parent 39349 2d0a4361c3ef
child 39443 e330437cd22a
equal deleted inserted replaced
39313:41ce0b56d858 39353:7f11d833d65b
     1 (* ========================================================================= *)
     1 (* ========================================================================= *)
     2 (* DERIVED RULES FOR CREATING FIRST ORDER LOGIC THEOREMS                     *)
     2 (* DERIVED RULES FOR CREATING FIRST ORDER LOGIC THEOREMS                     *)
     3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License *)
     3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License       *)
     4 (* ========================================================================= *)
     4 (* ========================================================================= *)
     5 
     5 
     6 structure Rule :> Rule =
     6 structure Rule :> Rule =
     7 struct
     7 struct
     8 
     8 
     9 open Useful;
     9 open Useful;
    10 
    10 
    11 (* ------------------------------------------------------------------------- *)
    11 (* ------------------------------------------------------------------------- *)
       
    12 (* Variable names.                                                           *)
       
    13 (* ------------------------------------------------------------------------- *)
       
    14 
       
    15 val xVarName = Name.fromString "x";
       
    16 val xVar = Term.Var xVarName;
       
    17 
       
    18 val yVarName = Name.fromString "y";
       
    19 val yVar = Term.Var yVarName;
       
    20 
       
    21 val zVarName = Name.fromString "z";
       
    22 val zVar = Term.Var zVarName;
       
    23 
       
    24 fun xIVarName i = Name.fromString ("x" ^ Int.toString i);
       
    25 fun xIVar i = Term.Var (xIVarName i);
       
    26 
       
    27 fun yIVarName i = Name.fromString ("y" ^ Int.toString i);
       
    28 fun yIVar i = Term.Var (yIVarName i);
       
    29 
       
    30 (* ------------------------------------------------------------------------- *)
    12 (*                                                                           *)
    31 (*                                                                           *)
    13 (* --------- reflexivity                                                     *)
    32 (* --------- reflexivity                                                     *)
    14 (*   x = x                                                                   *)
    33 (*   x = x                                                                   *)
    15 (* ------------------------------------------------------------------------- *)
    34 (* ------------------------------------------------------------------------- *)
    16 
    35 
    17 val reflexivity = Thm.refl (Term.Var "x");
    36 fun reflexivityRule x = Thm.refl x;
       
    37 
       
    38 val reflexivity = reflexivityRule xVar;
    18 
    39 
    19 (* ------------------------------------------------------------------------- *)
    40 (* ------------------------------------------------------------------------- *)
    20 (*                                                                           *)
    41 (*                                                                           *)
    21 (* --------------------- symmetry                                            *)
    42 (* --------------------- symmetry                                            *)
    22 (*   ~(x = y) \/ y = x                                                       *)
    43 (*   ~(x = y) \/ y = x                                                       *)
    23 (* ------------------------------------------------------------------------- *)
    44 (* ------------------------------------------------------------------------- *)
    24 
    45 
    25 val symmetry =
    46 fun symmetryRule x y =
    26     let
    47     let
    27       val x = Term.Var "x"
    48       val reflTh = reflexivityRule x
    28       and y = Term.Var "y"
       
    29       val reflTh = reflexivity
       
    30       val reflLit = Thm.destUnit reflTh
    49       val reflLit = Thm.destUnit reflTh
    31       val eqTh = Thm.equality reflLit [0] y
    50       val eqTh = Thm.equality reflLit [0] y
    32     in
    51     in
    33       Thm.resolve reflLit reflTh eqTh
    52       Thm.resolve reflLit reflTh eqTh
    34     end;
    53     end;
    35 
    54 
       
    55 val symmetry = symmetryRule xVar yVar;
       
    56 
    36 (* ------------------------------------------------------------------------- *)
    57 (* ------------------------------------------------------------------------- *)
    37 (*                                                                           *)
    58 (*                                                                           *)
    38 (* --------------------------------- transitivity                            *)
    59 (* --------------------------------- transitivity                            *)
    39 (*   ~(x = y) \/ ~(y = z) \/ x = z                                           *)
    60 (*   ~(x = y) \/ ~(y = z) \/ x = z                                           *)
    40 (* ------------------------------------------------------------------------- *)
    61 (* ------------------------------------------------------------------------- *)
    41 
    62 
    42 val transitivity =
    63 val transitivity =
    43     let
    64     let
    44       val x = Term.Var "x"
    65       val eqTh = Thm.equality (Literal.mkEq (yVar,zVar)) [0] xVar
    45       and y = Term.Var "y"
    66     in
    46       and z = Term.Var "z"
    67       Thm.resolve (Literal.mkEq (yVar,xVar)) symmetry eqTh
    47       val eqTh = Thm.equality (Literal.mkEq (y,z)) [0] x
       
    48     in
       
    49       Thm.resolve (Literal.mkEq (y,x)) symmetry eqTh
       
    50     end;
    68     end;
    51 
    69 
    52 (* ------------------------------------------------------------------------- *)
    70 (* ------------------------------------------------------------------------- *)
    53 (*   x = y \/ C                                                              *)
    71 (*   x = y \/ C                                                              *)
    54 (* -------------- symEq (x = y)                                              *)
    72 (* -------------- symEq (x = y)                                              *)
    57 
    75 
    58 fun symEq lit th =
    76 fun symEq lit th =
    59     let
    77     let
    60       val (x,y) = Literal.destEq lit
    78       val (x,y) = Literal.destEq lit
    61     in
    79     in
    62       if x = y then th
    80       if Term.equal x y then th
    63       else
    81       else
    64         let
    82         let
    65           val sub = Subst.fromList [("x",x),("y",y)]
    83           val sub = Subst.fromList [(xVarName,x),(yVarName,y)]
    66           val symTh = Thm.subst sub symmetry
    84           val symTh = Thm.subst sub symmetry
    67         in
    85         in
    68           Thm.resolve lit th symTh
    86           Thm.resolve lit th symTh
    69         end
    87         end
    70     end;
    88     end;
    74 (* t = u \/ C.                                                               *)
    92 (* t = u \/ C.                                                               *)
    75 (* ------------------------------------------------------------------------- *)
    93 (* ------------------------------------------------------------------------- *)
    76 
    94 
    77 type equation = (Term.term * Term.term) * Thm.thm;
    95 type equation = (Term.term * Term.term) * Thm.thm;
    78 
    96 
    79 fun ppEquation pp (eqn as (_,th)) = Thm.pp pp th;
    97 fun ppEquation (_,th) = Thm.pp th;
    80 
    98 
    81 fun equationToString x = Parser.toString ppEquation x;
    99 val equationToString = Print.toString ppEquation;
    82 
   100 
    83 fun equationLiteral (t_u,th) =
   101 fun equationLiteral (t_u,th) =
    84     let
   102     let
    85       val lit = Literal.mkEq t_u
   103       val lit = Literal.mkEq t_u
    86     in
   104     in
    88     end;
   106     end;
    89 
   107 
    90 fun reflEqn t = ((t,t), Thm.refl t);
   108 fun reflEqn t = ((t,t), Thm.refl t);
    91 
   109 
    92 fun symEqn (eqn as ((t,u), th)) =
   110 fun symEqn (eqn as ((t,u), th)) =
    93     if t = u then eqn
   111     if Term.equal t u then eqn
    94     else
   112     else
    95       ((u,t),
   113       ((u,t),
    96        case equationLiteral eqn of
   114        case equationLiteral eqn of
    97          SOME t_u => symEq t_u th
   115          SOME t_u => symEq t_u th
    98        | NONE => th);
   116        | NONE => th);
    99 
   117 
   100 fun transEqn (eqn1 as ((x,y), th1)) (eqn2 as ((_,z), th2)) =
   118 fun transEqn (eqn1 as ((x,y), th1)) (eqn2 as ((_,z), th2)) =
   101     if x = y then eqn2
   119     if Term.equal x y then eqn2
   102     else if y = z then eqn1
   120     else if Term.equal y z then eqn1
   103     else if x = z then reflEqn x
   121     else if Term.equal x z then reflEqn x
   104     else
   122     else
   105       ((x,z),
   123       ((x,z),
   106        case equationLiteral eqn1 of
   124        case equationLiteral eqn1 of
   107          NONE => th1
   125          NONE => th1
   108        | SOME x_y =>
   126        | SOME x_y =>
   109          case equationLiteral eqn2 of
   127          case equationLiteral eqn2 of
   110            NONE => th2
   128            NONE => th2
   111          | SOME y_z =>
   129          | SOME y_z =>
   112            let
   130            let
   113              val sub = Subst.fromList [("x",x),("y",y),("z",z)]
   131              val sub = Subst.fromList [(xVarName,x),(yVarName,y),(zVarName,z)]
   114              val th = Thm.subst sub transitivity
   132              val th = Thm.subst sub transitivity
   115              val th = Thm.resolve x_y th1 th
   133              val th = Thm.resolve x_y th1 th
   116              val th = Thm.resolve y_z th2 th
   134              val th = Thm.resolve y_z th2 th
   117            in
   135            in
   118              th
   136              th
   119            end);
   137            end);
   120 
   138 
   121 (*DEBUG
   139 (*MetisDebug
   122 val transEqn = fn eqn1 => fn eqn2 =>
   140 val transEqn = fn eqn1 => fn eqn2 =>
   123     transEqn eqn1 eqn2
   141     transEqn eqn1 eqn2
   124     handle Error err =>
   142     handle Error err =>
   125       raise Error ("Rule.transEqn:\neqn1 = " ^ equationToString eqn1 ^
   143       raise Error ("Rule.transEqn:\neqn1 = " ^ equationToString eqn1 ^
   126                    "\neqn2 = " ^ equationToString eqn2 ^ "\n" ^ err);
   144                    "\neqn2 = " ^ equationToString eqn2 ^ "\n" ^ err);
   147       res
   165       res
   148     end
   166     end
   149     handle Error err =>
   167     handle Error err =>
   150       (print (s ^ ": " ^ Term.toString tm ^ " --> Error: " ^ err ^ "\n");
   168       (print (s ^ ": " ^ Term.toString tm ^ " --> Error: " ^ err ^ "\n");
   151        raise Error (s ^ ": " ^ err));
   169        raise Error (s ^ ": " ^ err));
   152     
   170 
   153 fun thenConvTrans tm (tm',th1) (tm'',th2) =
   171 fun thenConvTrans tm (tm',th1) (tm'',th2) =
   154     let
   172     let
   155       val eqn1 = ((tm,tm'),th1)
   173       val eqn1 = ((tm,tm'),th1)
   156       and eqn2 = ((tm',tm''),th2)
   174       and eqn2 = ((tm',tm''),th2)
   157       val (_,th) = transEqn eqn1 eqn2
   175       val (_,th) = transEqn eqn1 eqn2
   187 fun everyConv [] tm = allConv tm
   205 fun everyConv [] tm = allConv tm
   188   | everyConv [conv] tm = conv tm
   206   | everyConv [conv] tm = conv tm
   189   | everyConv (conv :: convs) tm = thenConv conv (everyConv convs) tm;
   207   | everyConv (conv :: convs) tm = thenConv conv (everyConv convs) tm;
   190 
   208 
   191 fun rewrConv (eqn as ((x,y), eqTh)) path tm =
   209 fun rewrConv (eqn as ((x,y), eqTh)) path tm =
   192     if x = y then allConv tm
   210     if Term.equal x y then allConv tm
   193     else if null path then (y,eqTh)
   211     else if null path then (y,eqTh)
   194     else
   212     else
   195       let
   213       let
   196         val reflTh = Thm.refl tm
   214         val reflTh = Thm.refl tm
   197         val reflLit = Thm.destUnit reflTh
   215         val reflLit = Thm.destUnit reflTh
   204         val tm' = Term.replace tm (path,y)
   222         val tm' = Term.replace tm (path,y)
   205       in
   223       in
   206         (tm',th)
   224         (tm',th)
   207       end;
   225       end;
   208 
   226 
   209 (*DEBUG
   227 (*MetisDebug
   210 val rewrConv = fn eqn as ((x,y),eqTh) => fn path => fn tm =>
   228 val rewrConv = fn eqn as ((x,y),eqTh) => fn path => fn tm =>
   211     rewrConv eqn path tm
   229     rewrConv eqn path tm
   212     handle Error err =>
   230     handle Error err =>
   213       raise Error ("Rule.rewrConv:\nx = " ^ Term.toString x ^
   231       raise Error ("Rule.rewrConv:\nx = " ^ Term.toString x ^
   214                    "\ny = " ^ Term.toString y ^
   232                    "\ny = " ^ Term.toString y ^
   248       and h tm = tryConv (thenConv conv f) tm
   266       and h tm = tryConv (thenConv conv f) tm
   249     in
   267     in
   250       f
   268       f
   251     end;
   269     end;
   252 
   270 
   253 (*DEBUG
   271 (*MetisDebug
   254 val repeatTopDownConv = fn conv => fn tm =>
   272 val repeatTopDownConv = fn conv => fn tm =>
   255     repeatTopDownConv conv tm
   273     repeatTopDownConv conv tm
   256     handle Error err => raise Error ("repeatTopDownConv: " ^ err);
   274     handle Error err => raise Error ("repeatTopDownConv: " ^ err);
   257 *)
   275 *)
   258 
   276 
   271 fun thenLiterule literule1 literule2 lit =
   289 fun thenLiterule literule1 literule2 lit =
   272     let
   290     let
   273       val res1 as (lit',th1) = literule1 lit
   291       val res1 as (lit',th1) = literule1 lit
   274       val res2 as (lit'',th2) = literule2 lit'
   292       val res2 as (lit'',th2) = literule2 lit'
   275     in
   293     in
   276       if lit = lit' then res2
   294       if Literal.equal lit lit' then res2
   277       else if lit' = lit'' then res1
   295       else if Literal.equal lit' lit'' then res1
   278       else if lit = lit'' then allLiterule lit
   296       else if Literal.equal lit lit'' then allLiterule lit
   279       else
   297       else
   280         (lit'',
   298         (lit'',
   281          if not (Thm.member lit' th1) then th1
   299          if not (Thm.member lit' th1) then th1
   282          else if not (Thm.negateMember lit' th2) then th2
   300          else if not (Thm.negateMember lit' th2) then th2
   283          else Thm.resolve lit' th1 th2)
   301          else Thm.resolve lit' th1 th2)
   307   | everyLiterule [literule] lit = literule lit
   325   | everyLiterule [literule] lit = literule lit
   308   | everyLiterule (literule :: literules) lit =
   326   | everyLiterule (literule :: literules) lit =
   309     thenLiterule literule (everyLiterule literules) lit;
   327     thenLiterule literule (everyLiterule literules) lit;
   310 
   328 
   311 fun rewrLiterule (eqn as ((x,y),eqTh)) path lit =
   329 fun rewrLiterule (eqn as ((x,y),eqTh)) path lit =
   312     if x = y then allLiterule lit
   330     if Term.equal x y then allLiterule lit
   313     else
   331     else
   314       let
   332       let
   315         val th = Thm.equality lit path y
   333         val th = Thm.equality lit path y
   316         val th =
   334         val th =
   317             case equationLiteral eqn of
   335             case equationLiteral eqn of
   320         val lit' = Literal.replace lit (path,y)
   338         val lit' = Literal.replace lit (path,y)
   321       in
   339       in
   322         (lit',th)
   340         (lit',th)
   323       end;
   341       end;
   324 
   342 
   325 (*DEBUG
   343 (*MetisDebug
   326 val rewrLiterule = fn eqn => fn path => fn lit =>
   344 val rewrLiterule = fn eqn => fn path => fn lit =>
   327     rewrLiterule eqn path lit
   345     rewrLiterule eqn path lit
   328     handle Error err =>
   346     handle Error err =>
   329       raise Error ("Rule.rewrLiterule:\neqn = " ^ equationToString eqn ^
   347       raise Error ("Rule.rewrLiterule:\neqn = " ^ equationToString eqn ^
   330                    "\npath = " ^ Term.pathToString path ^
   348                    "\npath = " ^ Term.pathToString path ^
   382 
   400 
   383 fun literalRule literule lit th =
   401 fun literalRule literule lit th =
   384     let
   402     let
   385       val (lit',litTh) = literule lit
   403       val (lit',litTh) = literule lit
   386     in
   404     in
   387       if lit = lit' then th
   405       if Literal.equal lit lit' then th
   388       else if not (Thm.negateMember lit litTh) then litTh
   406       else if not (Thm.negateMember lit litTh) then litTh
   389       else Thm.resolve lit th litTh
   407       else Thm.resolve lit th litTh
   390     end;
   408     end;
   391 
   409 
   392 (*DEBUG
   410 (*MetisDebug
   393 val literalRule = fn literule => fn lit => fn th =>
   411 val literalRule = fn literule => fn lit => fn th =>
   394     literalRule literule lit th
   412     literalRule literule lit th
   395     handle Error err =>
   413     handle Error err =>
   396       raise Error ("Rule.literalRule:\nlit = " ^ Literal.toString lit ^
   414       raise Error ("Rule.literalRule:\nlit = " ^ Literal.toString lit ^
   397                    "\nth = " ^ Thm.toString th ^ "\n" ^ err);
   415                    "\nth = " ^ Thm.toString th ^ "\n" ^ err);
   410     end;
   428     end;
   411 
   429 
   412 fun allLiteralsRule literule th = literalsRule literule (Thm.clause th) th;
   430 fun allLiteralsRule literule th = literalsRule literule (Thm.clause th) th;
   413 
   431 
   414 fun convRule conv = allLiteralsRule (allArgumentsLiterule conv);
   432 fun convRule conv = allLiteralsRule (allArgumentsLiterule conv);
   415   
   433 
   416 (* ------------------------------------------------------------------------- *)
   434 (* ------------------------------------------------------------------------- *)
   417 (*                                                                           *)
   435 (*                                                                           *)
   418 (* ---------------------------------------------- functionCongruence (f,n)   *)
   436 (* ---------------------------------------------- functionCongruence (f,n)   *)
   419 (*   ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/                              *)
   437 (*   ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/                              *)
   420 (*   f x0 ... x{n-1} = f y0 ... y{n-1}                                       *)
   438 (*   f x0 ... x{n-1} = f y0 ... y{n-1}                                       *)
   421 (* ------------------------------------------------------------------------- *)
   439 (* ------------------------------------------------------------------------- *)
   422 
   440 
   423 fun functionCongruence (f,n) =
   441 fun functionCongruence (f,n) =
   424     let
   442     let
   425       val xs = List.tabulate (n, fn i => Term.Var ("x" ^ Int.toString i))
   443       val xs = List.tabulate (n,xIVar)
   426       and ys = List.tabulate (n, fn i => Term.Var ("y" ^ Int.toString i))
   444       and ys = List.tabulate (n,yIVar)
   427 
   445 
   428       fun cong ((i,yi),(th,lit)) =
   446       fun cong ((i,yi),(th,lit)) =
   429           let
   447           let
   430             val path = [1,i]
   448             val path = [1,i]
   431             val th = Thm.resolve lit th (Thm.equality lit path yi)
   449             val th = Thm.resolve lit th (Thm.equality lit path yi)
   447 (*   ~R x0 ... x{n-1} \/ R y0 ... y{n-1}                                     *)
   465 (*   ~R x0 ... x{n-1} \/ R y0 ... y{n-1}                                     *)
   448 (* ------------------------------------------------------------------------- *)
   466 (* ------------------------------------------------------------------------- *)
   449 
   467 
   450 fun relationCongruence (R,n) =
   468 fun relationCongruence (R,n) =
   451     let
   469     let
   452       val xs = List.tabulate (n, fn i => Term.Var ("x" ^ Int.toString i))
   470       val xs = List.tabulate (n,xIVar)
   453       and ys = List.tabulate (n, fn i => Term.Var ("y" ^ Int.toString i))
   471       and ys = List.tabulate (n,yIVar)
   454 
   472 
   455       fun cong ((i,yi),(th,lit)) =
   473       fun cong ((i,yi),(th,lit)) =
   456           let
   474           let
   457             val path = [i]
   475             val path = [i]
   458             val th = Thm.resolve lit th (Thm.equality lit path yi)
   476             val th = Thm.resolve lit th (Thm.equality lit path yi)
   475 
   493 
   476 fun symNeq lit th =
   494 fun symNeq lit th =
   477     let
   495     let
   478       val (x,y) = Literal.destNeq lit
   496       val (x,y) = Literal.destNeq lit
   479     in
   497     in
   480       if x = y then th
   498       if Term.equal x y then th
   481       else
   499       else
   482         let
   500         let
   483           val sub = Subst.fromList [("x",y),("y",x)]
   501           val sub = Subst.fromList [(xVarName,y),(yVarName,x)]
   484           val symTh = Thm.subst sub symmetry
   502           val symTh = Thm.subst sub symmetry
   485         in
   503         in
   486           Thm.resolve lit th symTh
   504           Thm.resolve lit th symTh
   487         end
   505         end
   488     end;
   506     end;
   543 
   561 
   544 local
   562 local
   545   fun expand lit =
   563   fun expand lit =
   546       let
   564       let
   547         val (x,y) = Literal.destNeq lit
   565         val (x,y) = Literal.destNeq lit
   548       in
   566         val _ = Term.isTypedVar x orelse Term.isTypedVar y orelse
   549         if (Term.isTypedVar x orelse Term.isTypedVar y) andalso x <> y then
   567                 raise Error "Rule.expandAbbrevs: no vars"
   550           Subst.unify Subst.empty x y
   568         val _ = not (Term.equal x y) orelse
   551         else raise Error "expand"
   569                 raise Error "Rule.expandAbbrevs: equal vars"
       
   570       in
       
   571         Subst.unify Subst.empty x y
   552       end;
   572       end;
   553 in
   573 in
   554   fun expandAbbrevs th =
   574   fun expandAbbrevs th =
   555       case LiteralSet.firstl (total expand) (Thm.clause th) of
   575       case LiteralSet.firstl (total expand) (Thm.clause th) of
   556         NONE => removeIrrefl th
   576         NONE => removeIrrefl th
   601 local
   621 local
   602   datatype edge =
   622   datatype edge =
   603       FactorEdge of Atom.atom * Atom.atom
   623       FactorEdge of Atom.atom * Atom.atom
   604     | ReflEdge of Term.term * Term.term;
   624     | ReflEdge of Term.term * Term.term;
   605 
   625 
   606   fun ppEdge p (FactorEdge atm_atm') = Parser.ppPair Atom.pp Atom.pp p atm_atm'
   626   fun ppEdge (FactorEdge atm_atm') = Print.ppPair Atom.pp Atom.pp atm_atm'
   607     | ppEdge p (ReflEdge tm_tm') = Parser.ppPair Term.pp Term.pp p tm_tm';
   627     | ppEdge (ReflEdge tm_tm') = Print.ppPair Term.pp Term.pp tm_tm';
   608 
   628 
   609   datatype joinStatus =
   629   datatype joinStatus =
   610       Joined
   630       Joined
   611     | Joinable of Subst.subst
   631     | Joinable of Subst.subst
   612     | Apart;
   632     | Apart;
   677       in
   697       in
   678         snd (List.foldl init ([],[]) acc)
   698         snd (List.foldl init ([],[]) acc)
   679       end
   699       end
   680     | init_edges acc apart ((sub,edge) :: sub_edges) =
   700     | init_edges acc apart ((sub,edge) :: sub_edges) =
   681       let
   701       let
   682 (*DEBUG
   702 (*MetisDebug
   683         val () = if not (Subst.null sub) then ()
   703         val () = if not (Subst.null sub) then ()
   684                  else raise Bug "Rule.factor.init_edges: empty subst"
   704                  else raise Bug "Rule.factor.init_edges: empty subst"
   685 *)
   705 *)
   686         val (acc,apart) =
   706         val (acc,apart) =
   687             case updateApart sub apart of
   707             case updateApart sub apart of
   730         fact acc others
   750         fact acc others
   731       end;
   751       end;
   732 in
   752 in
   733   fun factor' cl =
   753   fun factor' cl =
   734       let
   754       let
   735 (*TRACE6
   755 (*MetisTrace6
   736         val () = Parser.ppTrace LiteralSet.pp "Rule.factor': cl" cl
   756         val () = Print.trace LiteralSet.pp "Rule.factor': cl" cl
   737 *)
   757 *)
   738         val edges = mk_edges [] [] (LiteralSet.toList cl)
   758         val edges = mk_edges [] [] (LiteralSet.toList cl)
   739 (*TRACE6
   759 (*MetisTrace6
   740         val ppEdgesSize = Parser.ppMap length Parser.ppInt
   760         val ppEdgesSize = Print.ppMap length Print.ppInt
   741         val ppEdgel = Parser.ppList ppEdge
   761         val ppEdgel = Print.ppList ppEdge
   742         val ppEdges = Parser.ppList (Parser.ppTriple ppEdgel Subst.pp ppEdgel)
   762         val ppEdges = Print.ppList (Print.ppTriple ppEdgel Subst.pp ppEdgel)
   743         val () = Parser.ppTrace ppEdgesSize "Rule.factor': |edges|" edges
   763         val () = Print.trace ppEdgesSize "Rule.factor': |edges|" edges
   744         val () = Parser.ppTrace ppEdges "Rule.factor': edges" edges
   764         val () = Print.trace ppEdges "Rule.factor': edges" edges
   745 *)
   765 *)
   746         val result = fact [] edges
   766         val result = fact [] edges
   747 (*TRACE6
   767 (*MetisTrace6
   748         val ppResult = Parser.ppList Subst.pp
   768         val ppResult = Print.ppList Subst.pp
   749         val () = Parser.ppTrace ppResult "Rule.factor': result" result
   769         val () = Print.trace ppResult "Rule.factor': result" result
   750 *)
   770 *)
   751       in
   771       in
   752         result
   772         result
   753       end;
   773       end;
   754 end;
   774 end;