src/Tools/Metis/src/Rewrite.sml
changeset 72004 913162a47d9f
parent 45778 df6e210fb44c
child 74358 6ab3116a251a
equal deleted inserted replaced
72003:a7e6ac2dfa58 72004:913162a47d9f
     1 (* ========================================================================= *)
     1 (* ========================================================================= *)
     2 (* ORDERED REWRITING FOR FIRST ORDER TERMS                                   *)
     2 (* ORDERED REWRITING FOR FIRST ORDER TERMS                                   *)
     3 (* Copyright (c) 2003 Joe Hurd, distributed under the BSD License            *)
     3 (* Copyright (c) 2003 Joe Leslie-Hurd, distributed under the BSD License     *)
     4 (* ========================================================================= *)
     4 (* ========================================================================= *)
     5 
     5 
     6 structure Rewrite :> Rewrite =
     6 structure Rewrite :> Rewrite =
     7 struct
     7 struct
     8 
     8 
   217 in
   217 in
   218   fun addList rw = List.foldl uncurriedAdd rw;
   218   fun addList rw = List.foldl uncurriedAdd rw;
   219 end;
   219 end;
   220 
   220 
   221 (* ------------------------------------------------------------------------- *)
   221 (* ------------------------------------------------------------------------- *)
   222 (* Rewriting (the order must be a refinement of the rewrite order).          *)
   222 (* Rewriting (the supplied order must be a refinement of the rewrite order). *)
   223 (* ------------------------------------------------------------------------- *)
   223 (* ------------------------------------------------------------------------- *)
   224 
   224 
   225 local
   225 local
   226   fun reorder ((i,_),(j,_)) = Int.compare (j,i);
   226   fun reorder ((i,_),(j,_)) = Int.compare (j,i);
   227 in
   227 in
   287           fn tm =>
   287           fn tm =>
   288              if Term.equal tm l then (r,th) else raise Error "mkNeqConv: LR"
   288              if Term.equal tm l then (r,th) else raise Error "mkNeqConv: LR"
   289         end
   289         end
   290     end;
   290     end;
   291 
   291 
   292 datatype neqConvs = NeqConvs of Rule.conv LiteralMap.map;
   292 datatype neqConvs = NeqConvs of Rule.conv list;
   293 
   293 
   294 val neqConvsEmpty = NeqConvs (LiteralMap.new ());
   294 val neqConvsEmpty = NeqConvs [];
   295 
   295 
   296 fun neqConvsNull (NeqConvs m) = LiteralMap.null m;
   296 fun neqConvsNull (NeqConvs l) = List.null l;
   297 
   297 
   298 fun neqConvsAdd order (neq as NeqConvs m) lit =
   298 fun neqConvsAdd order (neq as NeqConvs l) lit =
   299     case total (mkNeqConv order) lit of
   299     case total (mkNeqConv order) lit of
   300       NONE => NONE
   300       NONE => neq
   301     | SOME conv => SOME (NeqConvs (LiteralMap.insert m (lit,conv)));
   301     | SOME conv => NeqConvs (conv :: l);
   302 
   302 
   303 fun mkNeqConvs order =
   303 fun mkNeqConvs order =
   304     let
   304     let
   305       fun add (lit,(neq,lits)) =
   305       fun add (lit,neq) = neqConvsAdd order neq lit
   306           case neqConvsAdd order neq lit of
   306     in
   307             SOME neq => (neq,lits)
   307       LiteralSet.foldl add neqConvsEmpty
   308           | NONE => (neq, LiteralSet.add lits lit)
   308     end;
   309     in
   309 
   310       LiteralSet.foldl add (neqConvsEmpty,LiteralSet.empty)
   310 fun buildNeqConvs order lits =
   311     end;
   311     let
   312 
   312       fun add (lit,(neq,neqs)) = (neqConvsAdd order neq lit, (lit,neq) :: neqs)
   313 fun neqConvsDelete (NeqConvs m) lit = NeqConvs (LiteralMap.delete m lit);
   313     in
   314 
   314       snd (LiteralSet.foldl add (neqConvsEmpty,[]) lits)
   315 fun neqConvsToConv (NeqConvs m) =
   315     end;
   316     Rule.firstConv (LiteralMap.foldr (fn (_,c,l) => c :: l) [] m);
   316 
   317 
   317 fun neqConvsToConv (NeqConvs l) = Rule.firstConv l;
   318 fun neqConvsFoldl f b (NeqConvs m) =
   318 
   319     LiteralMap.foldl (fn (l,_,z) => f (l,z)) b m;
   319 fun neqConvsUnion (NeqConvs l1) (NeqConvs l2) =
       
   320     NeqConvs (List.revAppend (l1,l2));
   320 
   321 
   321 fun neqConvsRewrIdLiterule order known redexes id neq =
   322 fun neqConvsRewrIdLiterule order known redexes id neq =
   322     if IntMap.null known andalso neqConvsNull neq then Rule.allLiterule
   323     if IntMap.null known andalso neqConvsNull neq then Rule.allLiterule
   323     else
   324     else
   324       let
   325       let
   330         Rule.allArgumentsLiterule conv
   331         Rule.allArgumentsLiterule conv
   331       end;
   332       end;
   332 
   333 
   333 fun rewriteIdEqn' order known redexes id (eqn as (l_r,th)) =
   334 fun rewriteIdEqn' order known redexes id (eqn as (l_r,th)) =
   334     let
   335     let
   335       val (neq,_) = mkNeqConvs order (Thm.clause th)
   336       val neq = mkNeqConvs order (Thm.clause th)
   336       val literule = neqConvsRewrIdLiterule order known redexes id neq
   337       val literule = neqConvsRewrIdLiterule order known redexes id neq
   337       val (strongEqn,lit) =
   338       val (strongEqn,lit) =
   338           case Rule.equationLiteral eqn of
   339           case Rule.equationLiteral eqn of
   339             NONE => (true, Literal.mkEq l_r)
   340             NONE => (true, Literal.mkEq l_r)
   340           | SOME lit => (false,lit)
   341           | SOME lit => (false,lit)
   353 
   354 
   354 fun rewriteIdLiteralsRule' order known redexes id lits th =
   355 fun rewriteIdLiteralsRule' order known redexes id lits th =
   355     let
   356     let
   356       val mk_literule = neqConvsRewrIdLiterule order known redexes id
   357       val mk_literule = neqConvsRewrIdLiterule order known redexes id
   357 
   358 
   358       fun rewr_neq_lit (lit, acc as (changed,neq,lits,th)) =
   359       fun rewr_neq_lit ((lit,rneq),(changed,lneq,lits,th)) =
   359           let
   360           let
   360             val neq = neqConvsDelete neq lit
   361             val neq = neqConvsUnion lneq rneq
   361             val (lit',litTh) = mk_literule neq lit
   362             val (lit',litTh) = mk_literule neq lit
       
   363             val lneq = neqConvsAdd order lneq lit'
       
   364             val lits = LiteralSet.add lits lit'
   362           in
   365           in
   363             if Literal.equal lit lit' then acc
   366             if Literal.equal lit lit' then (changed,lneq,lits,th)
   364             else
   367             else (true, lneq, lits, Thm.resolve lit th litTh)
   365               let
       
   366                 val th = Thm.resolve lit th litTh
       
   367               in
       
   368                 case neqConvsAdd order neq lit' of
       
   369                   SOME neq => (true,neq,lits,th)
       
   370                 | NONE => (changed, neq, LiteralSet.add lits lit', th)
       
   371               end
       
   372           end
   368           end
   373 
   369 
   374       fun rewr_neq_lits neq lits th =
   370       fun rewr_neq_lits lits th =
   375           let
   371           let
       
   372             val neqs = buildNeqConvs order lits
       
   373 
       
   374             val neq = neqConvsEmpty
       
   375             val lits = LiteralSet.empty
       
   376 
   376             val (changed,neq,lits,th) =
   377             val (changed,neq,lits,th) =
   377                 neqConvsFoldl rewr_neq_lit (false,neq,lits,th) neq
   378                 List.foldl rewr_neq_lit (false,neq,lits,th) neqs
   378           in
   379           in
   379             if changed then rewr_neq_lits neq lits th
   380             if changed then rewr_neq_lits lits th else (neq,th)
   380             else (neq,lits,th)
       
   381           end
   381           end
   382 
   382 
   383       val (neq,lits) = mkNeqConvs order lits
   383       val (neq,lits) = LiteralSet.partition Literal.isNeq lits
   384 
   384 
   385       val (neq,lits,th) = rewr_neq_lits neq lits th
   385       val (neq,th) = rewr_neq_lits neq th
   386 
   386 
   387       val rewr_literule = mk_literule neq
   387       val rewr_literule = mk_literule neq
   388 
   388 
   389       fun rewr_lit (lit,th) =
   389       fun rewr_lit (lit,th) =
   390           if Thm.member lit th then Rule.literalRule rewr_literule lit th
   390           if not (Thm.member lit th) then th
   391           else th
   391           else Rule.literalRule rewr_literule lit th
   392     in
   392     in
   393       LiteralSet.foldl rewr_lit th lits
   393       LiteralSet.foldl rewr_lit th lits
   394     end;
   394     end;
   395 
   395 
   396 fun rewriteIdRule' order known redexes id th =
   396 fun rewriteIdRule' order known redexes id th =
   404 *)
   404 *)
   405       val result = rewriteIdRule' order known redexes id th
   405       val result = rewriteIdRule' order known redexes id th
   406 (*MetisTrace6
   406 (*MetisTrace6
   407       val () = Print.trace Thm.pp "Rewrite.rewriteIdRule': result" result
   407       val () = Print.trace Thm.pp "Rewrite.rewriteIdRule': result" result
   408 *)
   408 *)
   409       val _ = not (thmReducible order known id result) orelse
   409       val () = if not (thmReducible order known id result) then ()
   410               raise Bug "rewriteIdRule: should be normalized"
   410                else raise Bug "Rewrite.rewriteIdRule': should be normalized"
       
   411     in
       
   412       result
       
   413     end
       
   414     handle Error err => raise Error ("Rewrite.rewriteIdRule':\n" ^ err);
       
   415 *)
       
   416 
       
   417 fun rewrIdConv (Rewrite {known,redexes,...}) order =
       
   418     rewrIdConv' order known redexes;
       
   419 
       
   420 fun rewrConv rewrite order = rewrIdConv rewrite order ~1;
       
   421 
       
   422 fun rewriteIdConv (Rewrite {known,redexes,...}) order =
       
   423     rewriteIdConv' order known redexes;
       
   424 
       
   425 fun rewriteConv rewrite order = rewriteIdConv rewrite order ~1;
       
   426 
       
   427 fun rewriteIdLiteralsRule (Rewrite {known,redexes,...}) order =
       
   428     rewriteIdLiteralsRule' order known redexes;
       
   429 
       
   430 fun rewriteLiteralsRule rewrite order =
       
   431     rewriteIdLiteralsRule rewrite order ~1;
       
   432 
       
   433 fun rewriteIdRule (Rewrite {known,redexes,...}) order =
       
   434     rewriteIdRule' order known redexes;
       
   435 
       
   436 (*MetisDebug
       
   437 val rewriteIdRule = fn rewr => fn order => fn id => fn th =>
       
   438     let
       
   439       val result = rewriteIdRule rewr order id th
       
   440 
       
   441       val th' = rewriteIdRule rewr order id result
       
   442 
       
   443       val () = if Thm.equal th' result then ()
       
   444                else
       
   445                  let
       
   446                    fun trace p s = Print.trace p ("Rewrite.rewriteIdRule: "^s)
       
   447                    val () = trace pp "rewr" rewr
       
   448                    val () = trace Thm.pp "th" th
       
   449                    val () = trace Thm.pp "result" result
       
   450                    val () = trace Thm.pp "th'" th'
       
   451                 in
       
   452                   raise Bug "Rewrite.rewriteIdRule: should be idempotent"
       
   453                 end
   411     in
   454     in
   412       result
   455       result
   413     end
   456     end
   414     handle Error err => raise Error ("Rewrite.rewriteIdRule:\n" ^ err);
   457     handle Error err => raise Error ("Rewrite.rewriteIdRule:\n" ^ err);
   415 *)
   458 *)
   416 
       
   417 fun rewrIdConv (Rewrite {known,redexes,...}) order =
       
   418     rewrIdConv' order known redexes;
       
   419 
       
   420 fun rewrConv rewrite order = rewrIdConv rewrite order ~1;
       
   421 
       
   422 fun rewriteIdConv (Rewrite {known,redexes,...}) order =
       
   423     rewriteIdConv' order known redexes;
       
   424 
       
   425 fun rewriteConv rewrite order = rewriteIdConv rewrite order ~1;
       
   426 
       
   427 fun rewriteIdLiteralsRule (Rewrite {known,redexes,...}) order =
       
   428     rewriteIdLiteralsRule' order known redexes;
       
   429 
       
   430 fun rewriteLiteralsRule rewrite order =
       
   431     rewriteIdLiteralsRule rewrite order ~1;
       
   432 
       
   433 fun rewriteIdRule (Rewrite {known,redexes,...}) order =
       
   434     rewriteIdRule' order known redexes;
       
   435 
   459 
   436 fun rewriteRule rewrite order = rewriteIdRule rewrite order ~1;
   460 fun rewriteRule rewrite order = rewriteIdRule rewrite order ~1;
   437 
   461 
   438 (* ------------------------------------------------------------------------- *)
   462 (* ------------------------------------------------------------------------- *)
   439 (* Inter-reduce the equations in the system.                                 *)
   463 (* Inter-reduce the equations in the system.                                 *)