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. *) |