ProgTutorial/Solutions.thy
changeset 469 7a558c5119b2
parent 458 242e81f4d461
child 517 d8c376662bb4
--- a/ProgTutorial/Solutions.thy	Mon Jun 20 13:59:58 2011 +0100
+++ b/ProgTutorial/Solutions.thy	Tue Jun 21 12:53:16 2011 +0100
@@ -35,6 +35,43 @@
 ML{*fun make_sum t1 t2 =
   HOLogic.mk_nat (HOLogic.dest_nat t1 + HOLogic.dest_nat t2) *}
 
+text {* \solution{fun:killqnt} *}
+
+ML %linenosgray{*val quantifiers = [@{const_name All}, @{const_name Ex}]
+
+fun kill_trivial_quantifiers trm =
+let
+  fun aux t =
+    case t of
+      Const (s1, T1) $ Abs (x, T2, t2) =>
+        if member (op =) quantifiers s1 andalso not (loose_bvar1 (t2, 0)) 
+        then incr_boundvars ~1 (aux t2)
+        else Const (s1, T1) $ Abs (x, T2, aux t2)
+    | t1 $ t2 => aux t1 $ aux t2
+    | Abs (s, T, t') => Abs (s, T, aux t')
+    | _ => t
+in 
+  aux trm
+end*}
+
+text {*
+  In line 7 we traverse the term, by first checking whether a term is an
+  application of a constant with an abstraction. If the constant stands for
+  a listed quantifier (see Line 1) and the bound variable does not occur
+  as a loose bound variable in the body, then we delete the quantifier. 
+  For this we have to increase all other dangling de Bruijn indices by
+  @{text "-1"} to account for the deleted quantifier. An example is 
+  as follows:
+
+  @{ML_response_fake [display,gray]
+  "@{prop \"\<forall>x y z. P x = P z\"}
+  |> kill_trivial_quantifiers
+  |> pretty_term @{context} 
+  |> pwriteln"
+  "\<forall>x z. P x = P z"}
+*}
+
+
 
 text {* \solution{fun:makelist} *}