test/Tools/isac/ADDTESTS/course/SignalProcess/Build_Inverse_Z_Transform.thy
author wneuper <walther.neuper@jku.at>
Thu, 29 Apr 2021 17:02:10 +0200
changeset 60270 844610c5c943
parent 60242 73ee61385493
child 60278 343efa173023
permissions -rw-r--r--
eliminate "handle _ => ..." finished
     1 (* Title:  Build_Inverse_Z_Transform
     2    Author: Jan Rocnik
     3    (c) copyright due to license terms.
     4 *)
     5 
     6 theory Build_Inverse_Z_Transform imports Isac.Inverse_Z_Transform
     7   
     8 begin
     9 
    10 text\<open>We stepwise build \ttfamily Inverse\_Z\_Transform.thy \normalfont as an 
    11   exercise. Because Subsection~\ref{sec:stepcheck} requires 
    12   \ttfamily Inverse\_Z\_Transform.thy \normalfont as a subtheory of \ttfamily 
    13   Isac.thy\normalfont, the setup has been changed from \ttfamily theory 
    14   Inverse\_Z\_Transform imports Isac \normalfont to the above one.
    15   \par \noindent
    16   \begin{center} 
    17   \textbf{Attention with the names of identifiers when going into internals!}
    18   \end{center}
    19   Here in this theory there are the internal names twice, for instance we have
    20   \ttfamily (Thm.derivation\_name @{thm rule1} = 
    21   "Build\_Inverse\_Z\_Transform.rule1") = true; \normalfont
    22   but actually in us will be \ttfamily Inverse\_Z\_Transform.rule1 \normalfont
    23 \<close>
    24 
    25 section \<open>Trials towards the Z-Transform\label{sec:trials}\<close>
    26 
    27 ML \<open>val thy = @{theory};\<close>
    28 
    29 subsection \<open>Notations and Terms\<close>
    30 text\<open>\noindent Try which notations we are able to use.\<close>
    31 ML \<open>
    32   @{term "1 < || z ||"};
    33   @{term "z / (z - 1)"};
    34   @{term "-u -n - 1"};
    35   @{term "-u [-n - 1]"}; (*[ ] denotes lists !!!*)
    36   @{term "z /(z - 1) = -u [-n - 1]"};
    37   @{term "1 < || z || ==> z / (z - 1) = -u [-n - 1]"};
    38   UnparseC.term @{term "1 < || z || ==> z / (z - 1) = -u [-n - 1]"};
    39 \<close>
    40 text\<open>\noindent Try which symbols we are able to use and how we generate them.\<close>
    41 ML \<open>
    42   (*alpha -->  "</alpha>" *)
    43   @{term "\<alpha> "};
    44   @{term "\<delta> "};
    45   @{term "\<phi> "};
    46   @{term "\<rho> "};
    47   UnparseC.term @{term "\<rho> "};
    48 \<close>
    49 
    50 subsection \<open>Rules\<close>
    51 (*axiomatization "z / (z - 1) = -u [-n - 1]"
    52   Illegal variable name: "z / (z - 1) = -u [-n - 1]" *)
    53 (*definition     "z / (z - 1) = -u [-n - 1]"
    54   Bad head of lhs: existing constant "op /"*)
    55 axiomatization where 
    56   rule1: "1 = \<delta>[n]" and
    57   rule2: "|| z || > 1 ==> z / (z - 1) = u [n]" and
    58   rule3: "|| z || < 1 ==> z / (z - 1) = -u [-n - 1]" and 
    59   rule4: "|| z || > || \<alpha> || ==> z / (z - \<alpha>) = \<alpha> \<up> n * u [n]" and
    60   rule5: "|| z || < || \<alpha> || ==> z / (z - \<alpha>) = -(\<alpha> \<up> n) * u [-n - 1]" and
    61   rule6: "|| z || > 1 ==> z/(z - 1) \<up> 2 = n * u [n]"
    62 
    63 text\<open>\noindent Check the rules for their correct notation. 
    64       (See the machine output.)\<close>
    65 ML \<open>
    66   @{thm rule1};
    67   @{thm rule2};
    68   @{thm rule3};
    69   @{thm rule4};
    70 \<close>
    71 
    72 subsection \<open>Apply Rules\<close>
    73 text\<open>\noindent We try to apply the rules to a given expression.\<close>
    74 
    75 ML \<open>
    76   val inverse_Z = Rule_Set.append_rules "inverse_Z" Rule_Set.empty
    77     [ Thm  ("rule3",ThmC.numerals_to_Free @{thm rule3}),
    78       Thm  ("rule4",ThmC.numerals_to_Free @{thm rule4}),
    79       Thm  ("rule1",ThmC.numerals_to_Free @{thm rule1})   
    80     ];
    81 
    82   val t = TermC.str2term "z / (z - 1) + z / (z - \<alpha>) + 1";
    83   val SOME (t', asm) = Rewrite.rewrite_set_ thy true inverse_Z t;
    84   UnparseC.term t' = "z / (z - ?\<delta> [?n]) + z / (z - \<alpha>) + ?\<delta> [?n]";
    85   (*
    86    * Attention rule1 is applied before the expression is 
    87    * checked for rule4 which would be correct!!!
    88    *)
    89 \<close>
    90 
    91 ML \<open>val (thy, ro, er) = (@{theory}, tless_true, eval_rls);\<close>
    92 ML \<open>
    93   val SOME (t, asm1) = 
    94     Rewrite.rewrite_ thy ro er true (ThmC.numerals_to_Free @{thm rule3}) t;
    95   UnparseC.term t = "- ?u [- ?n - 1] + z / (z - \<alpha>) + 1";
    96   (*- real *)
    97   UnparseC.term t;
    98 
    99   val SOME (t, asm2) = 
   100     Rewrite.rewrite_ thy ro er true (ThmC.numerals_to_Free @{thm rule4}) t;
   101   UnparseC.term t = "- ?u [- ?n - 1] + \<alpha> \<up> ?n * ?u [?n] + 1";
   102   (*- real *)
   103   UnparseC.term t;
   104 
   105   val SOME (t, asm3) = 
   106     Rewrite.rewrite_ thy ro er true (ThmC.numerals_to_Free @{thm rule1}) t;
   107   UnparseC.term t = "- ?u [- ?n - 1] + \<alpha> \<up> ?n * ?u [?n] + ?\<delta> [?n]";
   108   (*- real *)
   109   UnparseC.term t;
   110 \<close>
   111 ML \<open>UnparseC.terms (asm1 @ asm2 @ asm3);\<close>
   112 
   113 section\<open>Prepare Steps for TP-based programming Language\label{sec:prepstep}\<close>
   114 text\<open>
   115       \par \noindent The following sections are challenging with the CTP-based 
   116       possibilities of building the program. The goal is realized in 
   117       Section~\ref{spec-meth} and Section~\ref{prog-steps}.
   118       \par The reader is advised to jump between the subsequent subsections and 
   119       the respective steps in Section~\ref{prog-steps}. By comparing 
   120       Section~\ref{sec:calc:ztrans} the calculation can be comprehended step 
   121       by step.
   122 \<close>
   123 
   124 subsection \<open>Prepare Expression\label{prep-expr}\<close>
   125 text\<open>\noindent We try two different notations and check which of them 
   126        Isabelle can handle best.\<close>
   127 ML \<open>
   128   val ctxt = Proof_Context.init_global @{theory};
   129 (*val ctxt = ContextC.declare_constraints' [@{term "z::real"}] ctxt;*)
   130 
   131   val SOME fun1 = 
   132     TermC.parseNEW ctxt "X z = 3 / (z - 1/4 + -1/8 * z \<up> -1)"; UnparseC.term fun1;
   133   val SOME fun1' = 
   134     TermC.parseNEW ctxt "X z = 3 / (z - 1/4 + -1/8 * (1/z))"; UnparseC.term fun1';
   135 \<close>
   136 
   137 subsubsection \<open>Prepare Numerator and Denominator\<close>
   138 text\<open>\noindent The partial fraction decomposition is only possible if we
   139        get the bound variable out of the numerator. Therefor we divide
   140        the expression by $z$. Follow up the Calculation at 
   141        Section~\ref{sec:calc:ztrans} line number 02.\<close>
   142 
   143 axiomatization where
   144   ruleZY: "(X z = a / b) = (X' z = a / (z * b))"
   145 
   146 ML \<open>
   147   val (thy, ro, er) = (@{theory}, tless_true, eval_rls);
   148   val SOME (fun2, asm1) = 
   149     Rewrite.rewrite_ thy ro er true  @{thm ruleZY} fun1; UnparseC.term fun2;
   150   val SOME (fun2', asm1) = 
   151     Rewrite.rewrite_ thy ro er true  @{thm ruleZY} fun1'; UnparseC.term fun2';
   152 
   153   val SOME (fun3,_) = 
   154     Rewrite.rewrite_set_ @{theory} false norm_Rational fun2;
   155   UnparseC.term fun3;
   156   (*
   157    * Fails on x \<up> (-1)
   158    * We solve this problem by using 1/x as a workaround.
   159    *)
   160   val SOME (fun3',_) = 
   161     Rewrite.rewrite_set_ @{theory} false norm_Rational fun2';
   162   UnparseC.term fun3';
   163   (*
   164    * OK - workaround!
   165    *)
   166 \<close>
   167 
   168 subsubsection \<open>Get the Argument of the Expression X'\<close>
   169 text\<open>\noindent We use \texttt{grep} for finding possibilities how we can
   170        extract the bound variable in the expression. \ttfamily Prog_Expr.thy, 
   171        Tools.thy \normalfont contain general utilities: \ttfamily 
   172        eval\_argument\_in, eval\_rhs, eval\_lhs,\ldots \normalfont
   173        \ttfamily grep -r "fun eva\_" * \normalfont shows all functions 
   174        witch can be used in a script. Lookup this files how to build 
   175        and handle such functions.
   176        \par The next section shows how to introduce such a function.
   177 \<close>
   178 
   179 subsubsection\<open>Decompose the Given Term Into lhs and rhs\<close>
   180 ML \<open>
   181   val (_, expr) = HOLogic.dest_eq fun3'; UnparseC.term expr;
   182   val (_, denom) = 
   183     HOLogic.dest_bin "Rings.divide_class.divide" (type_of expr) expr;
   184   UnparseC.term denom = "-1 + -2 * z + 8 * z \<up> 2";
   185 \<close>
   186 
   187 text\<open>\noindent We have rhs\footnote{Note: lhs means \em Left Hand Side
   188       \normalfont and rhs means \em Right Hand Side \normalfont and indicates
   189       the left or the right part of an equation.} in the Program language, but
   190       we need a function which gets the denominator of a fraction.\<close>
   191 
   192 subsubsection\<open>Get the Denominator and Numerator out of a Fraction\<close>
   193 text\<open>\noindent The self written functions in e.g. \texttt{get\_denominator}
   194        should become a constant for the Isabelle parser:\<close>
   195 
   196 consts
   197   get_denominator :: "real => real"
   198   get_numerator :: "real => real"
   199 
   200 text \<open>\noindent With the above definition we run into problems when we parse
   201         the Program \texttt{InverseZTransform}. This leads to \em ambiguous
   202         parse trees. \normalfont We avoid this by moving the definition
   203         to \ttfamily Rational.thy \normalfont and re-building {\sisac}.
   204         \par \noindent ATTENTION: From now on \ttfamily 
   205         Build\_Inverse\_Z\_Transform \normalfont mimics a build from scratch;
   206         it only works due to re-building {\sisac} several times (indicated 
   207         explicitly).
   208 \<close>
   209 
   210 ML \<open>
   211 (*
   212  *("get_denominator",
   213  *  ("Rational.get_denominator", eval_get_denominator ""))
   214  *)
   215 fun eval_get_denominator (thmid:string) _ 
   216 		      (t as Const ("Rational.get_denominator", _) $
   217               (Const ("Rings.divide_class.divide", _) $num 
   218                 $denom)) thy = 
   219         SOME (TermC.mk_thmid thmid (UnparseC.term_in_thy thy denom) "", 
   220 	        HOLogic.Trueprop $ (TermC.mk_equality (t, denom)))
   221   | eval_get_denominator _ _ _ _ = NONE; 
   222 \<close>
   223 text \<open>\noindent For the tests of \ttfamily eval\_get\_denominator \normalfont
   224         see \ttfamily test/Knowledge/rational.sml\normalfont\<close>
   225 
   226 text \<open>\noindent \ttfamily get\_numerator \normalfont should also become a
   227         constant for the Isabelle parser, follow up the \texttt{const}
   228         declaration above.\<close>
   229 
   230 ML \<open>
   231 (*
   232  *("get_numerator",
   233  *  ("Rational.get_numerator", eval_get_numerator ""))
   234  *)
   235 fun eval_get_numerator (thmid:string) _ 
   236 		      (t as Const ("Rational.get_numerator", _) $
   237               (Const ("Rings.divide_class.divide", _) $num
   238                 $denom )) thy = 
   239         SOME (TermC.mk_thmid thmid (UnparseC.term_in_thy thy num) "", 
   240 	        HOLogic.Trueprop $ (TermC.mk_equality (t, num)))
   241   | eval_get_numerator _ _ _ _ = NONE; 
   242 \<close>
   243 
   244 text \<open>\noindent We discovered several problems by implementing the 
   245        \ttfamily get\_numerator \normalfont function. Remember when 
   246        putting new functions to {\sisac}, put them in a thy file and rebuild 
   247        {\sisac}, also put them in the ruleset for the script!\<close>
   248 
   249 subsection \<open>Solve Equation\label{sec:solveq}\<close>
   250 text \<open>\noindent We have to find the zeros of the term, therefor we use our
   251        \ttfamily get\_denominator \normalfont function from the step before
   252        and try to solve the second order equation. (Follow up the Calculation
   253        in Section~\ref{sec:calc:ztrans} Subproblem 2) Note: This type of
   254        equation is too general for the present program.
   255        \par We know that this equation can be categorized as \em univariate
   256        equation \normalfont and solved with the functions {\sisac} provides
   257        for this equation type. Later on {\sisac} should determine the type
   258        of the given equation self.\<close>
   259 ML \<open>
   260   val denominator = TermC.parseNEW ctxt "z \<up> 2 - 1/4*z - 1/8 = 0";
   261   val fmz = ["equality (z \<up> 2 - 1/4*z - 1/8 = (0::real))",
   262              "solveFor z",
   263              "solutions L"];
   264   val (dI',pI',mI') =("Isac_Knowledge", ["univariate", "equation"], ["no_met"]);
   265 \<close>
   266 text \<open>\noindent Check if the given equation matches the specification of this
   267         equation type.\<close>
   268 ML \<open>
   269   M_Match.match_pbl fmz (Problem.from_store ["univariate", "equation"]);
   270 \<close>
   271 
   272 text\<open>\noindent We switch up to the {\sisac} Context and try to solve the 
   273        equation with a more specific type definition.\<close>
   274 
   275 ML \<open>
   276   Context.theory_name thy = "Isac_Knowledge";
   277   val denominator = TermC.parseNEW ctxt "-1 + -2 * z + 8 * z \<up> 2 = 0";
   278   val fmz =                                             (*specification*)
   279     ["equality (-1 + -2 * z + 8 * z \<up> 2 = (0::real))",(*equality*)
   280      "solveFor z",                                      (*bound variable*)
   281      "solutions L"];                                    (*identifier for
   282                                                           solution*)
   283   val (dI',pI',mI') =
   284     ("Isac_Knowledge", 
   285       ["abcFormula", "degree_2", "polynomial", "univariate", "equation"],
   286       ["no_met"]);
   287 \<close>
   288 
   289 text \<open>\noindent Check if the (other) given equation matches the 
   290         specification of this equation type.\<close>
   291         
   292 ML \<open>
   293   M_Match.match_pbl fmz (Problem.from_store
   294     ["abcFormula", "degree_2", "polynomial", "univariate", "equation"]);
   295 \<close>
   296 
   297 text \<open>\noindent We stepwise solve the equation. This is done by the
   298         use of a so called calc tree seen downwards.\<close>
   299 
   300 ML \<open>
   301   val (p,_,f,nxt,_,pt) = CalcTreeTEST [(fmz, (dI',pI',mI'))];
   302   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   303   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   304   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   305   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   306   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   307   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   308   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   309   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   310   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   311   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   312   val (p,_,f,nxt,_,pt) = me nxt p [] pt;         
   313   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
   314   (*
   315    * nxt =..,Check_elementwise "Assumptions") 
   316    *)
   317   val (p,_,f,nxt,_,pt) = me nxt p [] pt;         
   318   val (p,_,f,nxt,_,pt) = me nxt p [] pt; f2str f;
   319   (*
   320    * [z = 1 / 2, z = -1 / 4]
   321    *)
   322   Test_Tool.show_pt pt; 
   323   val SOME f = parseNEW ctxt "[z=1/2, z=-1/4]";
   324 \<close>
   325 
   326 subsection \<open>Partial Fraction Decomposition\label{sec:pbz}\<close>
   327 text\<open>\noindent We go on with the decomposition of our expression. Follow up the
   328        Calculation in Section~\ref{sec:calc:ztrans} Step~3 and later on
   329        Subproblem~1.\<close>
   330 subsubsection \<open>Solutions of the Equation\<close>
   331 text\<open>\noindent We get the solutions of the before solved equation in a list.\<close>
   332 
   333 ML \<open>
   334   val SOME solutions = parseNEW ctxt "[z=1/2, z=-1/4]";
   335   UnparseC.term solutions;
   336   atomty solutions;
   337 \<close>
   338 
   339 subsubsection \<open>Get Solutions out of a List\<close>
   340 text \<open>\noindent In {\sisac}'s TP-based programming language: 
   341 \begin{verbatim}
   342   let $ $ s_1 = NTH 1 $ solutions; $ s_2 = NTH 2... $
   343 \end{verbatim}
   344        can be useful.
   345 \<close>
   346 
   347 ML \<open>
   348   val Const ("List.list.Cons", _) $ s_1 $ (Const ("List.list.Cons", _)
   349         $ s_2 $ Const ("List.list.Nil", _)) = solutions;
   350   UnparseC.term s_1;
   351   UnparseC.term s_2;
   352 \<close>
   353 
   354 text\<open>\noindent The ansatz for the \em Partial Fraction Decomposition \normalfont
   355       requires to get the denominators of the partial fractions out of the 
   356       Solutions as:
   357       \begin{itemize}
   358         \item $Denominator_{1}=z-Zeropoint_{1}$
   359         \item $Denominator_{2}=z-Zeropoint_{2}$
   360         \item \ldots
   361       \end{itemize}
   362 \<close>
   363       
   364 ML \<open>
   365   val xx = HOLogic.dest_eq s_1;
   366   val s_1' = HOLogic.mk_binop "Groups.minus_class.minus" xx;
   367   val xx = HOLogic.dest_eq s_2;
   368   val s_2' = HOLogic.mk_binop "Groups.minus_class.minus" xx;
   369   UnparseC.term s_1';
   370   UnparseC.term s_2';
   371 \<close>
   372 
   373 text \<open>\noindent For the programming language a function collecting all the 
   374         above manipulations is helpful.\<close>
   375 
   376 ML \<open>
   377   fun fac_from_sol s =
   378     let val (lhs, rhs) = HOLogic.dest_eq s
   379     in HOLogic.mk_binop "Groups.minus_class.minus" (lhs, rhs) end;
   380 \<close>
   381 
   382 ML \<open>
   383   fun mk_prod prod [] =
   384         if prod = TermC.empty
   385         then error "mk_prod called with []" 
   386         else prod
   387     | mk_prod prod (t :: []) =
   388         if prod = TermC.empty
   389         then t
   390         else HOLogic.mk_binop "Groups.times_class.times" (prod, t)
   391     | mk_prod prod (t1 :: t2 :: ts) =
   392           if prod = TermC.empty 
   393           then 
   394              let val p = 
   395                HOLogic.mk_binop "Groups.times_class.times" (t1, t2)
   396              in mk_prod p ts end 
   397           else 
   398              let val p =
   399                HOLogic.mk_binop "Groups.times_class.times" (prod, t1)
   400              in mk_prod p (t2 :: ts) end 
   401 \<close>
   402 (* ML {* 
   403 probably keep these test in test/Tools/isac/...
   404 (*mk_prod TermC.empty [];*)
   405 
   406 val prod = mk_prod TermC.empty [str2term "x + 123"]; 
   407 UnparseC.term prod = "x + 123";
   408 
   409 val sol = str2term "[z = 1 / 2, z = -1 / 4]";
   410 val sols = HOLogic.dest_list sol;
   411 val facs = map fac_from_sol sols;
   412 val prod = mk_prod TermC.empty facs; 
   413 UnparseC.term prod = "(z + -1 * (1 / 2)) * (z + -1 * (-1 / 4))";
   414 
   415 val prod = 
   416   mk_prod TermC.empty [str2term "x + 1", str2term "x + 2", str2term "x + 3"]; 
   417 UnparseC.term prod = "(x + 1) * (x + 2) * (x + 3)";
   418 *} *)
   419 ML \<open>
   420   fun factors_from_solution sol = 
   421     let val ts = HOLogic.dest_list sol
   422     in mk_prod TermC.empty (map fac_from_sol ts) end;
   423 \<close>
   424 (* ML {*
   425 val sol = str2term "[z = 1 / 2, z = -1 / 4]";
   426 val fs = factors_from_solution sol;
   427 UnparseC.term fs = "(z + -1 * (1 / 2)) * (z + -1 * (-1 / 4))"
   428 *} *)
   429 text \<open>\noindent This function needs to be packed such that it can be evaluated
   430         by the Lucas-Interpreter. Therefor we moved the function to the
   431         corresponding \ttfamily Equation.thy \normalfont in our case
   432         \ttfamily PartialFractions.thy \normalfont. The necessary steps
   433         are quit the same as we have done with \ttfamily get\_denominator 
   434         \normalfont before.\<close>
   435 ML \<open>
   436   (*("factors_from_solution",
   437     ("Partial_Fractions.factors_from_solution",
   438       eval_factors_from_solution ""))*)
   439       
   440   fun eval_factors_from_solution (thmid:string) _
   441       (t as Const ("Partial_Fractions.factors_from_solution", _) $ sol) thy =
   442         let val prod = factors_from_solution sol
   443         in SOME (TermC.mk_thmid thmid (UnparseC.term_in_thy thy prod) "",
   444              HOLogic.Trueprop $ (TermC.mk_equality (t, prod)))
   445         end
   446     | eval_factors_from_solution _ _ _ _ = NONE;
   447 \<close>
   448 
   449 text \<open>\noindent The tracing output of the calc tree after applying this
   450        function was:
   451 \begin{verbatim}
   452   24 / factors_from_solution [z = 1/ 2, z = -1 / 4])]
   453 \end{verbatim}
   454        and the next step:
   455 \begin{verbatim}
   456   val nxt = ("Empty_Tac", ...): tac'_)
   457 \end{verbatim}
   458        These observations indicate, that the Lucas-Interpreter (LIP) 
   459        does not know how to evaluate \ttfamily factors\_from\_solution
   460        \normalfont, so we knew that there is something wrong or missing.
   461 \<close>
   462        
   463 text\<open>\noindent First we isolate the difficulty in the program as follows:
   464 \begin{verbatim}      
   465   " (L_L::bool list) = (SubProblem (PolyEqX,      " ^
   466   "   [abcFormula, degree_2, polynomial,          " ^
   467   "    univariate,equation],                      " ^
   468   "   [no_met])                                   " ^
   469   "   [BOOL equ, REAL zzz]);                      " ^
   470   " (facs::real) = factors_from_solution L_L;     " ^
   471   " (foo::real) = Take facs                       " ^
   472 \end{verbatim}
   473 
   474       \par \noindent And see the tracing output:
   475       
   476 \begin{verbatim}
   477   [(([], Frm), Problem (Isac, [inverse, 
   478                                Z_Transform,
   479                                 SignalProcessing])),
   480    (([1], Frm), X z = 3 / (z - 1 / 4 + -1 / 8 * (1 / z))),
   481    (([1], Res), ?X' z = 3 / (z * (z - 1 / 4 + -1 / 8 * (1 / z)))),
   482    (([2], Res), ?X' z = 24 / (-1 + -2 * z + 8 * z \<up> 2)),
   483    (([3], Pbl), solve (-1 + -2 * z + 8 * z \<up> 2 = 0, z)),
   484    (([3,1], Frm), -1 + -2 * z + 8 * z \<up> 2 = 0),
   485    (([3,1], Res), z = (- -2 + sqrt (-2 \<up> 2 - 4 * 8 * -1)) / (2 * 8)|
   486                   z = (- -2 - sqrt (-2 \<up> 2 - 4 * 8 * -1)) / (2 * 8)),
   487    (([3,2], Res), z = 1 / 2 | z = -1 / 4),
   488    (([3,3], Res), [ z = 1 / 2, z = -1 / 4]),
   489    (([3,4], Res), [ z = 1 / 2, z = -1 / 4]),
   490    (([3], Res), [ z = 1 / 2, z = -1 / 4]),
   491    (([4], Frm), factors_from_solution [z = 1 / 2, z = -1 / 4])]
   492 \end{verbatim}      
   493       
   494       \par \noindent In particular that:
   495       
   496 \begin{verbatim}
   497   (([3], Pbl), solve (-1 + -2 * z + 8 * z \<up> 2 = 0, z)),
   498 \end{verbatim}
   499       \par \noindent Shows the equation which has been created in
   500       the program by: 
   501 \begin{verbatim}
   502   "(denom::real) = get_denominator funterm;      " ^ 
   503     (* get_denominator *)
   504   "(equ::bool) = (denom = (0::real));            " ^
   505 \end{verbatim}
   506         
   507       \noindent \ttfamily get\_denominator \normalfont has been evaluated successfully,
   508       but not\\ \ttfamily factors\_from\_solution.\normalfont
   509       So we stepwise compare with an analogous case, \ttfamily get\_denominator
   510       \normalfont successfully done above: We know that LIP evaluates
   511       expressions in the program by use of the \emph{srls}, so we try to get
   512       the original \emph{srls}.\\
   513 
   514 \begin{verbatim}
   515   val {srls,...} = MethodC.from_store ["SignalProcessing",
   516                             "Z_Transform",
   517                             "Inverse"];
   518 \end{verbatim}
   519           
   520       \par \noindent Create 2 good example terms:
   521 
   522 \begin{verbatim}
   523 val SOME t1 =
   524   parseNEW ctxt "get_denominator ((111::real) / 222)";
   525 val SOME t2 =
   526   parseNEW ctxt "factors_from_solution [(z::real)=1/2, z=-1/4]";
   527 \end{verbatim}
   528 
   529       \par \noindent Rewrite the terms using srls:\\
   530       \ttfamily \par \noindent rewrite\_set\_ thy true srls t1;\\
   531         rewrite\_set\_ thy true srls t2;\\
   532       \par \noindent \normalfont Now we see a difference: \texttt{t1} gives
   533       \texttt{SOME} but \texttt{t2} gives \texttt{NONE}. We look at the 
   534       \emph{srls}:
   535 \begin{verbatim}
   536   val srls = 
   537     Rule_Set.Repeat{id = "srls_InverseZTransform",
   538         rules = [Eval("Rational.get_numerator",
   539                    eval_get_numerator "Rational.get_numerator"),
   540                  Eval("Partial_Fractions.factors_from_solution",
   541                    eval_factors_from_solution 
   542                      "Partial_Fractions.factors_from_solution")]}
   543 \end{verbatim}                
   544       \par \noindent Here everthing is perfect. So the error can
   545       only be in the SML code of \ttfamily eval\_factors\_from\_solution.
   546       \normalfont We try to check the code with an existing test; since the 
   547       \emph{code} is in 
   548       \begin{center}\ttfamily src/Tools/isac/Knowledge/Partial\_Fractions.thy
   549       \normalfont\end{center}
   550       the \emph{test} should be in
   551       \begin{center}\ttfamily test/Tools/isac/Knowledge/partial\_fractions.sml
   552       \normalfont\end{center}
   553       \par \noindent After updating the function \ttfamily
   554       factors\_from\_solution \normalfont to a new version and putting a
   555       test-case to \ttfamily Partial\_Fractions.sml \normalfont we tried again
   556       to evaluate the term with the same result.
   557       \par We opened the test \ttfamily Test\_Isac.thy \normalfont and saw that
   558       everything is working fine. Also we checked that the test \ttfamily 
   559       partial\_fractions.sml \normalfont is used in \ttfamily Test\_Isac.thy 
   560       \normalfont
   561       \begin{center}use \ttfamily "Knowledge/partial\_fractions.sml"
   562       \normalfont \end{center}
   563       and \ttfamily Partial\_Fractions.thy \normalfont is part is part of
   564       {\sisac} by evaluating
   565 
   566 \begin{verbatim}
   567   val thy = @{theory "Inverse_Z_Transform"};
   568 \end{verbatim}
   569 
   570       After rebuilding {\sisac} again it worked.
   571 \<close>
   572 
   573 subsubsection \<open>Build Expression\<close>
   574 text \<open>\noindent In {\sisac}'s TP-based programming language we can build
   575        expressions by:\\
   576        \ttfamily let s\_1 = Take numerator / (s\_1 * s\_2) \normalfont\<close>
   577        
   578 ML \<open>
   579   (*
   580    * The main denominator is the multiplication of the denominators of
   581    * all partial fractions.
   582    *)
   583    
   584   val denominator' = HOLogic.mk_binop 
   585     "Groups.times_class.times" (s_1', s_2') ;
   586   val SOME numerator = parseNEW ctxt "3::real";
   587 
   588   val expr' = HOLogic.mk_binop
   589     "Rings.divide_class.divide" (numerator, denominator');
   590   UnparseC.term expr';
   591 \<close>
   592 
   593 subsubsection \<open>Apply the Partial Fraction Decomposion Ansatz\<close>
   594 
   595 text\<open>\noindent We use the Ansatz of the Partial Fraction Decomposition for our
   596       expression 2nd order. Follow up the calculation in 
   597       Section~\ref{sec:calc:ztrans} Step~03.\<close>
   598 
   599 ML \<open>Context.theory_name thy = "Isac_Knowledge"\<close>
   600 
   601 text\<open>\noindent We define two axiomatization, the first one is the main ansatz,
   602       the next one is just an equivalent transformation of the resulting
   603       equation. Both axiomatizations were moved to \ttfamily
   604       Partial\_Fractions.thy \normalfont and got their own rulesets. In later
   605       programs it is possible to use the rulesets and the machine will find
   606       the correct ansatz and equivalent transformation itself.\<close>
   607 
   608 axiomatization where
   609   ansatz_2nd_order: "n / (a*b) = A/a + B/b" and
   610   equival_trans_2nd_order: "(n/(a*b) = A/a + B/b) = (n = A*b + B*a)"
   611 
   612 text\<open>\noindent We use our \ttfamily ansatz\_2nd\_order \normalfont to rewrite
   613        our expression and get an equation with our expression on the left
   614        and the partial fractions of it on the right hand side.\<close>
   615   
   616 ML \<open>
   617   val SOME (t1,_) = 
   618     rewrite_ @{theory} e_rew_ord Rule_Set.empty false 
   619              @{thm ansatz_2nd_order} expr';
   620   UnparseC.term t1; atomty t1;
   621   val eq1 = HOLogic.mk_eq (expr', t1);
   622   UnparseC.term eq1;
   623 \<close>
   624 
   625 text\<open>\noindent Eliminate the denominators by multiplying the left and the
   626       right hand side of the equation with the main denominator. This is an
   627       simple equivalent transformation. Later on we use an own ruleset
   628       defined in \ttfamily Partial\_Fractions.thy \normalfont for doing this.
   629       Follow up the calculation in Section~\ref{sec:calc:ztrans} Step~04.\<close>
   630 
   631 ML \<open>
   632   val SOME (eq2,_) = 
   633     rewrite_ @{theory} e_rew_ord Rule_Set.empty false 
   634              @{thm equival_trans_2nd_order} eq1;
   635   UnparseC.term eq2;
   636 \<close>
   637 
   638 text\<open>\noindent We use the existing ruleset \ttfamily norm\_Rational \normalfont 
   639      for simplifications on expressions.\<close>
   640 
   641 ML \<open>
   642   val SOME (eq3,_) = rewrite_set_ @{theory} false norm_Rational eq2;
   643   UnparseC.term eq3;
   644   (*
   645    * ?A ?B not simplified
   646    *)
   647 \<close>
   648 
   649 text\<open>\noindent In Example~\ref{eg:gap} of my thesis I'm describing a problem about
   650       simplifications. The problem that we would like to have only a specific degree
   651       of simplification occurs right here, in the next step.\<close>
   652 
   653 ML \<open>
   654   Rewrite.trace_on := false;
   655   val SOME fract1 =
   656     parseNEW ctxt "(z - 1/2)*(z - -1/4) * (A/(z - 1/2) + B/(z - -1/4))";
   657   (*
   658    * A B !
   659    *)
   660   val SOME (fract2,_) = 
   661     rewrite_set_ @{theory} false norm_Rational fract1;
   662   UnparseC.term fract2 = "(A + -2 * B + 4 * A * z + 4 * B * z) / 4";
   663   (*
   664    * UnparseC.term fract2 = "A * (1 / 4 + z) + B * (-1 / 2 + z)" 
   665    * would be more traditional...
   666    *)
   667 \<close>
   668 
   669 text\<open>\noindent We walk around this problem by generating our new equation first.\<close>
   670 
   671 ML \<open>
   672   val (numerator, denominator) = HOLogic.dest_eq eq3;
   673   val eq3' = HOLogic.mk_eq (numerator, fract1);
   674   (*
   675    * A B !
   676    *)
   677   UnparseC.term eq3';
   678   (*
   679    * MANDATORY: simplify (and remove denominator) otherwise 3 = 0
   680    *)
   681   val SOME (eq3'' ,_) = 
   682     rewrite_set_ @{theory} false norm_Rational eq3';
   683   UnparseC.term eq3'';
   684 \<close>
   685 
   686 text\<open>\noindent Still working at {\sisac}\ldots\<close>
   687 
   688 ML \<open>Context.theory_name thy = "Isac_Knowledge"\<close>
   689 
   690 subsubsection \<open>Build a Rule-Set for the Ansatz\<close>
   691 text \<open>\noindent The \emph{ansatz} rules violate the principle that each
   692        variable on the right-hand-side must also occur on the
   693        left-hand-side of the rule: A, B, etc. don't do that. Thus the
   694        rewriter marks these variables with question marks: ?A, ?B, etc.
   695        These question marks can be dropped by \ttfamily fun
   696        drop\_questionmarks\normalfont.\<close>
   697        
   698 ML \<open>
   699   val ansatz_rls = prep_rls @{theory} (
   700     Rule_Set.Repeat {id = "ansatz_rls", preconds = [], rew_ord = ("dummy_ord",dummy_ord),
   701       erls = Rule_Set.empty, srls = Rule_Set.Empty, calc = [], errpatts = [],
   702       rules = [
   703         Thm ("ansatz_2nd_order",ThmC.numerals_to_Free @{thm ansatz_2nd_order}),
   704         Thm ("equival_trans_2nd_order",ThmC.numerals_to_Free @{thm equival_trans_2nd_order})
   705               ], 
   706       scr = Empty_Prog});
   707 \<close>
   708 
   709 text\<open>\noindent We apply the ruleset\ldots\<close>
   710 
   711 ML \<open>
   712   val SOME (ttttt,_) = 
   713     rewrite_set_ @{theory} false ansatz_rls expr';
   714 \<close>
   715 
   716 text\<open>\noindent And check the output\ldots\<close>
   717 
   718 ML \<open>
   719   UnparseC.term expr' = "3 / ((z - 1 / 2) * (z - -1 / 4))";
   720   UnparseC.term ttttt = "?A / (z - 1 / 2) + ?B / (z - -1 / 4)";
   721 \<close>
   722 
   723 subsubsection \<open>Get the First Coefficient\<close>
   724 
   725 text\<open>\noindent Now it's up to get the two coefficients A and B, which will be
   726       the numerators of our partial fractions. Continue following up the 
   727       Calculation in Section~\ref{sec:calc:ztrans} Subproblem~1.\<close>
   728       
   729 text\<open>\noindent To get the first coefficient we substitute $z$ with the first
   730       zero-point we determined in Section~\ref{sec:solveq}.\<close>
   731 
   732 ML \<open>
   733   val SOME (eq4_1,_) =
   734     rewrite_terms_ @{theory} e_rew_ord Rule_Set.empty [s_1] eq3'';
   735   UnparseC.term eq4_1;
   736   val SOME (eq4_2,_) =
   737     rewrite_set_ @{theory} false norm_Rational eq4_1;
   738   UnparseC.term eq4_2;
   739 
   740   val fmz = ["equality (3=3*A/(4::real))", "solveFor A", "solutions L"];
   741   val (dI',pI',mI') =("Isac_Knowledge", ["univariate", "equation"], ["no_met"]);
   742   (*
   743    * Solve the simple linear equation for A:
   744    * Return eq, not list of eq's
   745    *)
   746   val (p,_,fa,nxt,_,pt) = CalcTreeTEST [(fmz, (dI',pI',mI'))];
   747   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   748     (*Add_Given "equality (3=3*A/4)"*)
   749   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   750     (*Add_Given "solveFor A"*)
   751   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   752     (*Add_Find "solutions L"*)
   753   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   754     (*Specify_Theory "Isac_Knowledge"*)
   755   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   756     (*Specify_Problem ["normalise", "polynomial",
   757                        "univariate", "equation"])*)
   758   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   759     (* Specify_Method["PolyEq", "normalise_poly"]*)
   760   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   761     (*Apply_Method["PolyEq", "normalise_poly"]*)
   762   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   763     (*Rewrite ("all_left", "PolyEq.all_left")*)
   764   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   765     (*Rewrite_Set_Inst(["(''bdv'',A)"],"make_ratpoly_in")*)
   766   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   767     (*Rewrite_Set "polyeq_simplify"*)
   768   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   769   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   770   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   771     (*Add_Given "equality (3 + -3 / 4 * A =0)"*)
   772   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   773     (*Add_Given "solveFor A"*)
   774   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   775     (*Add_Find "solutions A_i"*)
   776   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   777   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   778   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   779   val (p,_,fa,nxt,_,pt) = me nxt p [] pt; 
   780     (*Apply_Method ["PolyEq", "solve_d1_polyeq_equation"]*)
   781   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   782     (*Rewrite_Set_Inst(["(''bdv'',A)"],"d1_polyeq_simplify")*)
   783   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   784     (*Rewrite_Set "polyeq_simplify"*)
   785   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   786     (*Rewrite_Set "norm_Rational_parenthesized"*)
   787   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   788     (*Or_to_List*)
   789   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   790     (*Check_elementwise "Assumptions"*)
   791   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   792     (*Check_Postcond ["degree_1", "polynomial",
   793                       "univariate", "equation"]*)
   794   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   795     (*Check_Postcond ["normalise", "polynomial",
   796                       "univariate", "equation"]*)
   797   val (p,_,fa,nxt,_,pt) = me nxt p [] pt;
   798     (*End_Proof'*)
   799   f2str fa;
   800 \<close>
   801 
   802 subsubsection \<open>Get Second Coefficient\<close>
   803 
   804 text\<open>\noindent With the use of \texttt{thy} we check which theories the 
   805       interpreter knows.\<close>
   806 
   807 ML \<open>thy\<close>
   808 
   809 text\<open>\noindent To get the second coefficient we substitute $z$ with the second
   810       zero-point we determined in Section~\ref{sec:solveq}.\<close>
   811 
   812 ML \<open>
   813   val SOME (eq4b_1,_) =
   814     rewrite_terms_ @{theory} e_rew_ord Rule_Set.empty [s_2] eq3'';
   815   UnparseC.term eq4b_1;
   816   val SOME (eq4b_2,_) =
   817     rewrite_set_ @{theory} false norm_Rational eq4b_1;
   818   UnparseC.term eq4b_2;
   819 
   820   val fmz = ["equality (3= -3*B/(4::real))", "solveFor B", "solutions L"];
   821   val (dI',pI',mI') =("Isac_Knowledge", ["univariate", "equation"], ["no_met"]);
   822   val (p,_,fb,nxt,_,pt) = CalcTreeTEST [(fmz, (dI',pI',mI'))];
   823   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   824   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   825   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   826   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   827   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   828   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   829   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   830   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   831   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   832   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   833   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   834   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   835   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   836   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   837   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   838   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   839   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   840   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   841   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   842   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   843   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   844   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   845   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   846   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   847   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   848   val (p,_,fb,nxt,_,pt) = me nxt p [] pt;
   849   val (p,_,fb,nxt,_,pt) = me nxt p [] pt; 
   850   f2str fb;
   851 \<close>
   852 
   853 text\<open>\noindent We compare our results with the pre calculated upshot.\<close>
   854 
   855 ML \<open>
   856   if f2str fa = "[A = 4]" then () else error "part.fract. eq4_1";
   857   if f2str fb = "[B = -4]" then () else error "part.fract. eq4_1";
   858 \<close>
   859 
   860 section \<open>Implement the Specification and the MethodC \label{spec-meth}\<close>
   861 
   862 text\<open>\noindent Now everything we need for solving the problem has been
   863       tested out. We now start by creating new nodes for our methods and
   864       further on our new program in the interpreter.\<close>
   865 
   866 subsection\<open>Define the Field Descriptions for the 
   867             Specification\label{sec:deffdes}\<close>
   868 
   869 text\<open>\noindent We define the fields \em filterExpression \normalfont and
   870       \em stepResponse \normalfont both as equations, they represent the in- and
   871       output of the program.\<close>
   872 
   873 consts
   874   filterExpression  :: "bool => una"
   875   stepResponse      :: "bool => una"
   876 
   877 subsection\<open>Define the Specification\<close>
   878 
   879 text\<open>\noindent The next step is defining the specifications as nodes in the
   880       designated part. We have to create the hierarchy node by node and start
   881       with \em SignalProcessing \normalfont and go on by creating the node
   882       \em Z\_Transform\normalfont.\<close>
   883 
   884 setup \<open>KEStore_Elems.add_pbts
   885   [Problem.prep_input thy "pbl_SP" [] Problem.id_empty (["SignalProcessing"], [], Rule_Set.empty, NONE, []),
   886     Problem.prep_input thy "pbl_SP_Ztrans" [] Problem.id_empty
   887       (["Z_Transform", "SignalProcessing"], [], Rule_Set.empty, NONE, [])]\<close>
   888 
   889 text\<open>\noindent For the suddenly created node we have to define the input
   890        and output parameters. We already prepared their definition in
   891        Section~\ref{sec:deffdes}.\<close>
   892 
   893 setup \<open>KEStore_Elems.add_pbts
   894   [Problem.prep_input thy "pbl_SP_Ztrans_inv" [] Problem.id_empty
   895       (["Inverse", "Z_Transform", "SignalProcessing"],
   896         [("#Given" ,["filterExpression X_eq"]),
   897           ("#Find", ["stepResponse n_eq"])],
   898         Rule_Set.append_rules "empty" Rule_Set.empty [(*for preds in where_*)],
   899         NONE,
   900         [["SignalProcessing", "Z_Transform", "Inverse"]])]\<close>
   901 ML \<open>
   902   Test_Tool.show_ptyps() ();
   903   Problem.from_store ["Inverse", "Z_Transform", "SignalProcessing"];
   904 \<close>
   905 
   906 subsection \<open>Define Name and Signature for the MethodC\<close>
   907 
   908 text\<open>\noindent As a next step we store the definition of our new method as a
   909       constant for the interpreter.\<close>
   910 
   911 consts
   912   InverseZTransform :: "[bool, bool] => bool"
   913     ("((Program InverseZTransform (_ =))// (_))" 9)
   914 
   915 subsection \<open>Setup Parent Nodes in Hierarchy of MethodC\label{sec:cparentnode}\<close>
   916 
   917 text\<open>\noindent Again we have to generate the nodes step by step, first the
   918       parent node and then the originally \em Z\_Transformation 
   919       \normalfont node. We have to define both nodes first with an empty script
   920       as content.\<close>
   921 
   922 setup \<open>KEStore_Elems.add_mets
   923   [MethodC.prep_input thy "met_SP" [] e_metID
   924       (["SignalProcessing"], [],
   925         {rew_ord'="tless_true", rls'= Rule_Set.empty, calc = [], srls = Rule_Set.empty, prls = Rule_Set.empty, crls = Rule_Set.empty,
   926           errpats = [], nrls = Rule_Set.empty},
   927         "empty_script"),
   928     MethodC.prep_input thy "met_SP_Ztrans" [] e_metID
   929       (["SignalProcessing", "Z_Transform"], [],
   930         {rew_ord'="tless_true", rls'= Rule_Set.empty, calc = [], srls = Rule_Set.empty, prls = Rule_Set.empty, crls = Rule_Set.empty,
   931           errpats = [], nrls = Rule_Set.empty},
   932         "empty_script")]
   933 \<close>
   934 
   935 text\<open>\noindent After we generated both nodes, we can fill the containing
   936       script we want to implement later. First we define the specifications
   937       of the script in e.g. the in- and output.\<close>
   938 
   939 setup \<open>KEStore_Elems.add_mets
   940   [MethodC.prep_input thy "met_SP_Ztrans_inv" [] e_metID
   941       (["SignalProcessing", "Z_Transform", "Inverse"], 
   942         [("#Given" ,["filterExpression X_eq", "boundVariable X_z"]),
   943           ("#Find", ["stepResponse n_eq"])],
   944         {rew_ord'="tless_true", rls'= Rule_Set.empty, calc = [], srls = Rule_Set.empty, prls = Rule_Set.empty, crls = Rule_Set.empty,
   945           errpats = [], nrls = Rule_Set.empty},
   946         "empty_script")]
   947 \<close>
   948 
   949 text\<open>\noindent After we stored the definition we can start implementing the
   950       script itself. As a first try we define only three rows containing one
   951       simple operation.\<close>
   952 
   953 setup \<open>KEStore_Elems.add_mets
   954   [MethodC.prep_input thy "met_SP_Ztrans_inv" [] e_metID
   955       (["SignalProcessing", "Z_Transform", "Inverse"], 
   956         [("#Given" , ["filterExpression X_eq", "boundVariable X_z"]),
   957           ("#Find", ["stepResponse n_eq"])],
   958         {rew_ord'="tless_true", rls'= Rule_Set.empty, calc = [], srls = Rule_Set.empty, prls = Rule_Set.empty, crls = Rule_Set.empty,
   959           errpats = [], nrls = Rule_Set.empty},
   960         "Program InverseZTransform (Xeq::bool) =" ^ (*TODO boundVariable X_z*)
   961           " (let X = Take Xeq;" ^
   962           "      X = Rewrite ruleZY X" ^
   963           "  in X)")]
   964 \<close>
   965 
   966 text\<open>\noindent Check if the method has been stored correctly\ldots\<close>
   967 
   968 ML \<open>
   969   show_mets(); 
   970 \<close>
   971 
   972 text\<open>\noindent If yes we can get the method by stepping backwards through
   973       the hierarchy.\<close>
   974 
   975 ML \<open>
   976   MethodC.from_store ["SignalProcessing", "Z_Transform", "Inverse"];
   977 \<close>
   978 
   979 section \<open>Program in TP-based language \label{prog-steps}\<close>
   980 
   981 text\<open>\noindent We start stepwise expanding our program. The script is a
   982       simple string containing several manipulation instructions.
   983       \par The first script we try contains no instruction, we only test if
   984       building scripts that way work.\<close>
   985 
   986 subsection \<open>Stepwise Extend the Program\<close>
   987 ML \<open>
   988   val str = 
   989     "Program InverseZTransform (Xeq::bool) =                          "^
   990     " Xeq";
   991 \<close>
   992 
   993 text\<open>\noindent Next we put some instructions in the script and try if we are
   994       able to solve our first equation.\<close>
   995 
   996 ML \<open>
   997   val str = 
   998     "Program InverseZTransform (Xeq::bool) =                          "^
   999     (*
  1000      * 1/z) instead of z \<up> -1
  1001      *)
  1002     " (let X = Take Xeq;                                             "^
  1003     "      X' = Rewrite ruleZY False X;                              "^
  1004     (*
  1005      * z * denominator
  1006      *)
  1007     "      X' = (Rewrite_Set norm_Rational False) X'                 "^
  1008     (*
  1009      * simplify
  1010      *)
  1011     "  in X)";
  1012     (*
  1013      * NONE
  1014      *)
  1015     "Program InverseZTransform (Xeq::bool) =                          "^
  1016     (*
  1017      * (1/z) instead of z \<up> -1
  1018      *)
  1019     " (let X = Take Xeq;                                             "^
  1020     "      X' = Rewrite ruleZY False X;                              "^
  1021     (*
  1022      * z * denominator
  1023      *)
  1024     "      X' = (Rewrite_Set norm_Rational False) X';                "^
  1025     (*
  1026      * simplify
  1027      *)
  1028     "      X' = (SubProblem (IsacX,[pqFormula,degree_2,              "^
  1029     "                               polynomial,univariate,equation], "^
  1030     "                              [no_met])                         "^
  1031     "                              [BOOL e_e, REAL v_v])             "^
  1032     "            in X)";
  1033 \<close>
  1034 
  1035 text\<open>\noindent To solve the equation it is necessary to drop the left hand
  1036       side, now we only need the denominator of the right hand side. The first
  1037       equation solves the zeros of our expression.\<close>
  1038 
  1039 ML \<open>
  1040   val str = 
  1041     "Program InverseZTransform (Xeq::bool) =                          "^
  1042     " (let X = Take Xeq;                                             "^
  1043     "      X' = Rewrite ruleZY False X;                              "^
  1044     "      X' = (Rewrite_Set norm_Rational False) X';                "^
  1045     "      funterm = rhs X'                                          "^
  1046     (*
  1047      * drop X'= for equation solving
  1048      *)
  1049     "  in X)";
  1050 \<close>
  1051 
  1052 text\<open>\noindent As mentioned above, we need the denominator of the right hand
  1053       side. The equation itself consists of this denominator and tries to find
  1054       a $z$ for this the denominator is equal to zero.\<close>
  1055 
  1056 text \<open> dropped during switch from Program to partial_function:
  1057   val str = 
  1058     "Program InverseZTransform (X_eq::bool) =                         "^
  1059     " (let X = Take X_eq;                                            "^
  1060     "      X' = Rewrite ruleZY False X;                              "^
  1061     "      X' = (Rewrite_Set norm_Rational False) X';                "^
  1062     "      (X'_z::real) = lhs X';                                    "^
  1063     "      (z::real) = argument_in X'_z;                             "^
  1064     "      (funterm::real) = rhs X';                                 "^
  1065     "      (denom::real) = get_denominator funterm;                  "^
  1066     (*
  1067      * get_denominator
  1068      *)
  1069     "      (equ::bool) = (denom = (0::real));                        "^
  1070     "      (L_L::bool list) =                                        "^
  1071     "            (SubProblem (Test,                                 "^
  1072     "                         [LINEAR,univariate,equation,test],     "^
  1073     "                         [Test,solve_linear])                   "^
  1074     "                         [BOOL equ, REAL z])                    "^
  1075     "  in X)";
  1076 
  1077   parse thy str;
  1078   val sc = (inst_abs o Thm.term_of o the o (parse thy)) str;
  1079   atomty sc;
  1080 \<close>
  1081 
  1082 text \<open>\noindent This ruleset contains all functions that are in the script; 
  1083        The evaluation of the functions is done by rewriting using this ruleset.\<close>
  1084 
  1085 ML \<open>
  1086   val srls = 
  1087     Rule_Set.Repeat {id="srls_InverseZTransform", 
  1088          preconds = [],
  1089          rew_ord = ("termlessI",termlessI),
  1090          erls = Rule_Set.append_rules "erls_in_srls_InverseZTransform" Rule_Set.empty
  1091            [(*for asm in NTH_CONS ...*)
  1092             Eval ("Orderings.ord_class.less",eval_equ "#less_"),
  1093             (*2nd NTH_CONS pushes n+-1 into asms*)
  1094             Eval("Groups.plus_class.plus", eval_binop "#add_")
  1095            ], 
  1096          srls = Rule_Set.Empty, calc = [], errpatts = [],
  1097          rules = [
  1098                   Thm ("NTH_CONS",ThmC.numerals_to_Free @{thm NTH_CONS}),
  1099                   Eval("Groups.plus_class.plus", eval_binop "#add_"),
  1100                   Thm ("NTH_NIL",ThmC.numerals_to_Free @{thm NTH_NIL}),
  1101                   Eval("Prog_Expr.lhs", eval_lhs"eval_lhs_"),
  1102                   Eval("Prog_Expr.rhs", eval_rhs"eval_rhs_"),
  1103                   Eval("Prog_Expr.argument'_in", eval_argument_in "Prog_Expr.argument'_in"),
  1104                   Eval("Rational.get_denominator", eval_get_denominator "#get_denominator"),
  1105                   Eval("Rational.get_numerator", eval_get_numerator "#get_numerator"),
  1106                   Eval("Partial_Fractions.factors_from_solution",
  1107                        eval_factors_from_solution "#factors_from_solution"),
  1108                   Eval("Partial_Fractions.drop_questionmarks",
  1109                        eval_drop_questionmarks "#drop_?")
  1110                  ],
  1111          scr = Empty_Prog};
  1112 \<close>
  1113 
  1114 
  1115 subsection \<open>Store Final Version of Program for Execution\<close>
  1116 
  1117 text\<open>\noindent After we also tested how to write scripts and run them,
  1118       we start creating the final version of our script and store it into
  1119       the method for which we created a node in Section~\ref{sec:cparentnode}
  1120       Note that we also did this stepwise, but we didn't kept every
  1121       subversion.\<close>
  1122 
  1123 setup \<open>KEStore_Elems.add_mets
  1124   [MethodC.prep_input thy "met_SP_Ztrans_inv" [] e_metID
  1125       (["SignalProcessing", "Z_Transform", "Inverse"], 
  1126         [("#Given" , ["filterExpression X_eq"]), (*TODO boundVariable X_z*)
  1127           ("#Find", ["stepResponse n_eq"])],
  1128         {rew_ord'="tless_true", rls'= Rule_Set.empty, calc = [], srls = srls, prls = Rule_Set.empty, crls = Rule_Set.empty,
  1129           errpats = [], nrls = Rule_Set.empty},
  1130         "Program InverseZTransform (X_eq::bool) =                        "^
  1131           (*(1/z) instead of z \<up> -1*)
  1132           "(let X = Take X_eq;                                            "^
  1133           "      X' = Rewrite ruleZY False X;                             "^
  1134           (*z * denominator*)
  1135           "      (num_orig::real) = get_numerator (rhs X');               "^
  1136           "      X' = (Rewrite_Set norm_Rational False) X';               "^
  1137           (*simplify*)
  1138           "      (X'_z::real) = lhs X';                                   "^
  1139           "      (zzz::real) = argument_in X'_z;                          "^
  1140           "      (funterm::real) = rhs X';                                "^
  1141           (*drop X' z = for equation solving*)
  1142           "      (denom::real) = get_denominator funterm;                 "^
  1143           (*get_denominator*)
  1144           "      (num::real) = get_numerator funterm;                     "^
  1145           (*get_numerator*)
  1146           "      (equ::bool) = (denom = (0::real));                       "^
  1147           "      (L_L::bool list) = (SubProblem (PolyEqX,                 "^
  1148           "         [abcFormula,degree_2,polynomial,univariate,equation], "^
  1149           "         [no_met])                                             "^
  1150           "         [BOOL equ, REAL zzz]);                                "^
  1151           "      (facs::real) = factors_from_solution L_L;                "^
  1152           "      (eql::real) = Take (num_orig / facs);                    "^ 
  1153 
  1154           "      (eqr::real) = (Try (Rewrite_Set ansatz_rls False)) eql;  "^
  1155 
  1156           "      (eq::bool) = Take (eql = eqr);                           "^
  1157           (*Maybe possible to use HOLogic.mk_eq ??*)
  1158           "      eq = (Try (Rewrite_Set equival_trans False)) eq;         "^ 
  1159 
  1160           "      eq = drop_questionmarks eq;                              "^
  1161           "      (z1::real) = (rhs (NTH 1 L_L));                          "^
  1162           (* 
  1163           * prepare equation for a - eq_a
  1164           * therefor substitute z with solution 1 - z1
  1165           *)
  1166           "      (z2::real) = (rhs (NTH 2 L_L));                          "^
  1167 
  1168           "      (eq_a::bool) = Take eq;                                  "^
  1169           "      eq_a = (Substitute [zzz=z1]) eq;                         "^
  1170           "      eq_a = (Rewrite_Set norm_Rational False) eq_a;           "^
  1171           "      (sol_a::bool list) =                                     "^
  1172           "                 (SubProblem (IsacX,                           "^
  1173           "                              [univariate,equation],[no_met])  "^
  1174           "                              [BOOL eq_a, REAL (A::real)]);    "^
  1175           "      (a::real) = (rhs(NTH 1 sol_a));                          "^
  1176 
  1177           "      (eq_b::bool) = Take eq;                                  "^
  1178           "      eq_b =  (Substitute [zzz=z2]) eq_b;                      "^
  1179           "      eq_b = (Rewrite_Set norm_Rational False) eq_b;           "^
  1180           "      (sol_b::bool list) =                                     "^
  1181           "                 (SubProblem (IsacX,                           "^
  1182           "                              [univariate,equation],[no_met])  "^
  1183           "                              [BOOL eq_b, REAL (B::real)]);    "^
  1184           "      (b::real) = (rhs(NTH 1 sol_b));                          "^
  1185 
  1186           "      eqr = drop_questionmarks eqr;                            "^
  1187           "      (pbz::real) = Take eqr;                                  "^
  1188           "      pbz = ((Substitute [A=a, B=b]) pbz);                     "^
  1189 
  1190           "      pbz = Rewrite ruleYZ False pbz;                          "^
  1191           "      pbz = drop_questionmarks pbz;                            "^
  1192 
  1193           "      (X_z::bool) = Take (X_z = pbz);                          "^
  1194           "      (n_eq::bool) = (Rewrite_Set inverse_z False) X_z;        "^
  1195           "      n_eq = drop_questionmarks n_eq                           "^
  1196           "in n_eq)")]
  1197 \<close>
  1198 
  1199 
  1200 subsection \<open>Check the Program\<close>
  1201 text\<open>\noindent When the script is ready we can start checking our work.\<close>
  1202 subsubsection \<open>Check the Formalization\<close>
  1203 text\<open>\noindent First we want to check the formalization of the in and
  1204        output of our program.\<close>
  1205 
  1206 ML \<open>
  1207   val fmz = 
  1208     ["filterExpression (X  = 3 / (z - 1/4 + -1/8 * (1/(z::real))))",
  1209      "stepResponse (x[n::real]::bool)"];
  1210   val (dI,pI,mI) = 
  1211     ("Isac_Knowledge", ["Inverse", "Z_Transform", "SignalProcessing"], 
  1212              ["SignalProcessing", "Z_Transform", "Inverse"]);
  1213 
  1214   val ([
  1215           (
  1216             1,
  1217             [1],
  1218             "#Given",
  1219             Const ("Inverse_Z_Transform.filterExpression", _),
  1220             [Const ("HOL.eq", _) $ _ $ _]
  1221           ),
  1222           (
  1223             2,
  1224             [1],
  1225             "#Find",
  1226             Const ("Inverse_Z_Transform.stepResponse", _),
  1227             [Free ("x", _) $ _]
  1228           )
  1229        ],_
  1230       ) = O_Model.init fmz thy ((#ppc o Problem.from_store) pI);
  1231 
  1232   val Prog sc 
  1233     = (#scr o MethodC.from_store) ["SignalProcessing",
  1234                         "Z_Transform",
  1235                         "Inverse"];
  1236   atomty sc;
  1237 \<close>
  1238 
  1239 subsubsection \<open>Stepwise Check the Program\label{sec:stepcheck}\<close>
  1240 text\<open>\noindent We start to stepwise execute our new program in a calculation
  1241       tree and check if every node implements that what we have wanted.\<close>
  1242       
  1243 ML \<open>
  1244   Rewrite.trace_on := false; (*true*)
  1245   LItool.trace_on := false; (*true*)
  1246   print_depth 9;
  1247   
  1248   val fmz =
  1249     ["filterExpression (X z = 3 / ((z::real) + 1/10 - 1/50*(1/z)))",
  1250      "stepResponse (x[n::real]::bool)"];
  1251      
  1252   val (dI,pI,mI) =
  1253     ("Isac_Knowledge", ["Inverse", "Z_Transform", "SignalProcessing"], 
  1254              ["SignalProcessing", "Z_Transform", "Inverse"]);
  1255              
  1256   val (p,_,f,nxt,_,pt)  = CalcTreeTEST [(fmz, (dI,pI,mI))];
  1257   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1258     "Add_Given";
  1259   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1260     "Add_Find";
  1261   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1262     "Specify_Theory";
  1263   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1264     "Specify_Problem";
  1265   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1266     "Specify_Method";
  1267   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1268     "Apply_Method";
  1269   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1270     "Rewrite (ruleZY, Inverse_Z_Transform.ruleZY)";
  1271     "--> X z = 3 / (z - 1 / 4 + -1 / 8 * (1 / z))";
  1272   (*
  1273    * TODO naming!
  1274    *)
  1275   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1276     "Rewrite_Set norm_Rational";
  1277     " --> X' z = 3 / (z * (z - 1 / 4 + -1 / 8 * (1 / z)))";
  1278   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1279     "SubProblem";
  1280   print_depth 3;
  1281 \<close>
  1282 
  1283 text \<open>\noindent Instead of \ttfamily nxt = Subproblem \normalfont above we had
  1284        \ttfamily Empty\_Tac; \normalfont the search for the reason considered
  1285        the following points:\begin{itemize}
  1286        \item What shows \ttfamily show\_pt pt;\normalfont\ldots?
  1287 \begin{verbatim}(([2], Res), ?X' z = 24 / (-1 + -2 * z + 8 * z \<up> 2))]\end{verbatim}
  1288          The calculation is ok but no \ttfamily next \normalfont step found:
  1289          Should be\\ \ttfamily nxt = Subproblem\normalfont!
  1290        \item What shows \ttfamily trace\_script := true; \normalfont we read
  1291          bottom up\ldots
  1292      \begin{verbatim}
  1293      @@@next leaf 'SubProblem
  1294      (PolyEq',[abcFormula, degree_2, polynomial, 
  1295                univariate, equation], no_meth)
  1296      [BOOL equ, REAL z]' 
  1297        ---> Program.Tac 'SubProblem (PolyEq',
  1298               [abcFormula, degree_2, polynomial,
  1299                univariate, equation], no_meth)
  1300      [BOOL (-1 + -2 * z + 8 * z \^\^\^ ~2 = 0), REAL z]'
  1301      \end{verbatim}
  1302          We see the SubProblem with correct arguments from searching next
  1303          step (program text !!!--->!!! Program.Tac (script tactic) with arguments
  1304          evaluated.)
  1305      \item Do we have the right Program \ldots difference in the
  1306          arguments in the arguments\ldots
  1307          \begin{verbatim}
  1308      val Prog s =
  1309      (#scr o MethodC.from_store) ["SignalProcessing",
  1310                        "Z_Transform",
  1311                        "Inverse"];
  1312      writeln (UnparseC.term s);
  1313          \end{verbatim}
  1314          \ldots shows the right script. Difference in the arguments.
  1315      \item Test --- Why helpless here ? --- shows: \ttfamily replace
  1316          no\_meth by [no\_meth] \normalfont in Program
  1317      \end{itemize}
  1318 \<close>
  1319 
  1320 ML \<open>
  1321   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1322     (*Model_Problem";*)
  1323 \<close>
  1324 
  1325 text \<open>\noindent Instead of \ttfamily nxt = Model\_Problem \normalfont above
  1326        we had \ttfamily Empty\_Tac; \normalfont the search for the reason 
  1327        considered the following points:\begin{itemize}
  1328        \item Difference in the arguments
  1329        \item Comparison with Subsection~\ref{sec:solveq}: There solving this
  1330          equation works, so there must be some difference in the arguments
  1331          of the Subproblem: RIGHT: we had \ttfamily [no\_meth] \normalfont
  1332          instead of \ttfamily [no\_met] \normalfont ;-)
  1333        \end{itemize}\<close>
  1334 
  1335 ML \<open>
  1336   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1337     (*Add_Given equality (-1 + -2 * z + 8 * z \<up> 2 = 0)";*)
  1338   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1339     (*Add_Given solveFor z";*)
  1340   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1341     (*Add_Find solutions z_i";*)
  1342   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1343     (*Specify_Theory Isac";*)
  1344 \<close>
  1345 
  1346 text \<open>\noindent We had \ttfamily nxt = Empty\_Tac instead Specify\_Theory;
  1347        \normalfont The search for the reason considered the following points:
  1348        \begin{itemize}
  1349        \item Was there an error message? NO -- ok
  1350        \item Has \ttfamily nxt = Add\_Find \normalfont been inserted in pt:\\
  1351          \ttfamily get\_obj g\_pbl pt (fst p);\normalfont? YES -- ok
  1352        \item What is the returned formula:
  1353 \begin{verbatim}
  1354 print_depth 999; f; print_depth 3;
  1355 { Find = [ Correct "solutions z_i"],
  1356   With = [],
  1357   Given = [Correct "equality (-1 + -2*z + 8*z \<up> 2 = 0)",
  1358            Correct "solveFor z"],
  1359   Where = [...],
  1360   Relate = [] }
  1361 \end{verbatim}
  1362      \normalfont The only False is the reason: the Where (the precondition) is
  1363      False for good reasons: The precondition seems to check for linear
  1364      equations, not for the one we want to solve! Removed this error by
  1365      correcting the Program from \ttfamily SubProblem (PolyEq',
  1366      \lbrack linear,univariate,equation,
  1367        test\rbrack, \lbrack Test,solve\_linear\rbrack \normalfont to
  1368      \ttfamily SubProblem (PolyEq',\\ \lbrack abcFormula,degree\_2,
  1369        polynomial,univariate,equation\rbrack,\\
  1370                    \lbrack PolyEq,solve\_d2\_polyeq\_abc\_equation
  1371                    \rbrack\normalfont
  1372      You find the appropriate type of equation at the
  1373      {\sisac}-WEB-Page\footnote{
  1374      \href{http://www.ist.tugraz.at/projects/isac/www/kbase/pbl/index\_pbl.html}
  1375           {http://www.ist.tugraz.at/projects/isac/www/kbase/pbl/index\_pbl.html}
  1376                                }
  1377      And the respective method in \ttfamily Knowledge/PolyEq.thy \normalfont
  1378      at the respective \ttfamily store\_pbt. \normalfont Or you leave the
  1379      selection of the appropriate type to isac as done in the final Program ;-))
  1380   \end{itemize}\<close>
  1381   
  1382 ML \<open>
  1383   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1384     (*Specify_Problem [abcFormula,...";*)
  1385   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1386     (*Specify_Method [PolyEq,solve_d2_polyeq_abc_equation";*)
  1387   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1388     (*Apply_Method [PolyEq,solve_d2_polyeq_abc_equation";*)
  1389   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1390     (*Rewrite_Set_Inst [(''bdv'', z)], d2_polyeq_abcFormula_simplify";*)
  1391   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1392   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1393   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1394   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1395   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1396   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1397   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1398   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1399   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1400   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1401   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1402   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1403   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1404   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1405   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1406   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1407   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1408     (*Specify_Problem ["normalise", "polynomial", "univariate", "equation"]*)
  1409   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1410     (*Specify_Method ["PolyEq", "normalise_poly"]*)
  1411   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1412     (*Apply_Method ["PolyEq", "normalise_poly"]*)
  1413   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1414     (*Rewrite ("all_left", "PolyEq.all_left")*)
  1415   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1416     (*Rewrite_Set_Inst (["(''bdv'', A)"], "make_ratpoly_in")*)
  1417   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1418     (*Rewrite_Set "polyeq_simplify"*)
  1419   val (p,_,f,nxt,_,pt) = me nxt p [] pt; 
  1420     (*Subproblem("Isac_Knowledge",["degree_1", "polynomial", "univariate", "equation"])*)
  1421   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1422   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1423   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1424   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1425   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1426   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1427   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1428   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1429   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1430   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1431   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1432   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1433   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1434   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1435   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1436   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1437   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1438   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1439   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1440   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1441   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1442   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1443   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1444   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1445   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1446   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1447   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1448   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1449   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1450   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1451   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1452   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1453   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1454   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1455   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1456   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1457   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1458   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1459   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1460   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1461   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1462   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1463   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1464   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1465   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1466   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([11, 4, 5], Res) Check_Postcond*)
  1467   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([11, 4], Res) Check_Postcond*)
  1468   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([11], Res) Take*)
  1469   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([12], Frm) Substitute*)
  1470   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([12], Res) Rewrite*)
  1471   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([13], Res) Take*)
  1472   val (p,_,f,nxt,_,pt) = me nxt p [] pt; (*([14], Frm) Empty_Tac*)
  1473 \<close>
  1474 ML \<open>
  1475   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1476 \<close>
  1477 ML \<open>
  1478   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1479 \<close>
  1480 ML \<open>
  1481   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1482 \<close>
  1483 ML \<open>
  1484   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1485 \<close>
  1486 ML \<open>
  1487   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1488 \<close>
  1489 ML \<open>
  1490   val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1491 \<close>
  1492 
  1493 ML \<open>
  1494 LItool.trace_on := true;
  1495 \<close>
  1496 ML \<open>
  1497 val (p,_,f,nxt,_,pt) = me nxt p [] pt;
  1498 \<close>
  1499 ML \<open>
  1500 Test_Tool.show_pt pt;
  1501 \<close>
  1502 ML \<open>
  1503 \<close> 
  1504 ML \<open>
  1505 \<close> 
  1506 ML \<open>
  1507 \<close> 
  1508 ML \<open>
  1509 \<close> 
  1510 ML \<open>
  1511 \<close> 
  1512 ML \<open>
  1513 \<close> 
  1514 
  1515 text\<open>\noindent As a last step we check the tracing output of the last calc
  1516       tree instruction and compare it with the pre-calculated result.\<close>
  1517 
  1518 section \<open>Improve and Transfer into Knowledge\<close>
  1519 text \<open>
  1520   We want to improve the very long program \ttfamily InverseZTransform
  1521   \normalfont by modularisation: partial fraction decomposition shall
  1522   become a sub-problem.
  1523 
  1524   We could transfer all knowledge in \ttfamily Build\_Inverse\_Z\_Transform.thy 
  1525   \normalfont first to the \ttfamily Knowledge/Inverse\_Z\_Transform.thy 
  1526   \normalfont and then modularise. In this case TODO problems?!?
  1527 
  1528   We chose another way and go bottom up: first we build the sub-problem in
  1529   \ttfamily Partial\_Fractions.thy \normalfont with the term:
  1530 
  1531       $$\frac{3}{x\cdot(z - \frac{1}{4} + \frac{-1}{8}\cdot\frac{1}{z})}$$
  1532 
  1533   \noindent (how this still can be improved see \ttfamily Partial\_Fractions.thy\normalfont),
  1534   and re-use all stuff prepared in \ttfamily Build\_Inverse\_Z\_Transform.thy:
  1535   \normalfont The knowledge will be transferred to \ttfamily src/../Partial\_Fractions.thy 
  1536   \normalfont and the respective tests to:
  1537   \begin{center}\ttfamily test/../sartial\_fractions.sml\normalfont\end{center}
  1538 \<close>
  1539 
  1540 subsection \<open>Transfer to Partial\_Fractions.thy\<close>
  1541 text \<open>
  1542   First we transfer both, knowledge and tests into:
  1543   \begin{center}\ttfamily src/../Partial\_Fractions.thy\normalfont\end{center}
  1544   in order to immediately have the test results.
  1545 
  1546   We copy \ttfamily factors\_from\_solution, drop\_questionmarks,\\
  1547   ansatz\_2nd\_order \normalfont and rule-sets --- no problem.
  1548   
  1549   Also \ttfamily store\_pbt ..\\ "pbl\_simp\_rat\_partfrac"
  1550   \normalfont is easy.
  1551 
  1552   But then we copy from:\\
  1553   (1) \ttfamily Build\_Inverse\_Z\_Transform.thy store\_met\ldots "met\_SP\_Ztrans\_inv"
  1554   \normalfont\\ to\\ 
  1555   (2) \ttfamily Partial\_Fractions.thy store\_met\ldots "met\_SP\_Ztrans\_inv" 
  1556   \normalfont\\ and cut out the respective part from the program. First we ensure that
  1557   the string is correct. When we insert the string into (2)
  1558   \ttfamily store\_met .. "met\_partial\_fraction" \normalfont --- and get an error.
  1559 \<close>
  1560 
  1561 subsubsection \<open>'Programming' in ISAC's TP-based Language\<close>
  1562 text \<open>
  1563   At the present state writing programs in {\sisac} is particularly cumbersome.
  1564   So we give hints how to cope with the many obstacles. Below we describe the
  1565   steps we did in making (2) run.
  1566   
  1567   \begin{enumerate}
  1568     \item We check if the \textbf{string} containing the program is correct.
  1569     \item We check if the \textbf{types in the program} are correct.
  1570       For this purpose we start start with the first and last lines
  1571      \begin{verbatim}
  1572      "PartFracScript (f_f::real) (v_v::real) =       " ^
  1573      " (let X = Take f_f;                            " ^
  1574      "      pbz = ((Substitute []) X)                " ^
  1575      "  in pbz)"
  1576      \end{verbatim}
  1577        The last but one line helps not to bother with ';'.
  1578      \item Then we add line by line. Already the first line causes the error. 
  1579         So we investigate it by
  1580       \begin{verbatim}
  1581       val ctxt = Proof_Context.init_global @{theory "Inverse_Z_Transform"} ;
  1582       val SOME t = 
  1583         parseNEW ctxt "(num_orig::real) = 
  1584                           get_numerator(rhs f_f)";
  1585       \end{verbatim}
  1586         and see a type clash: \ttfamily rhs \normalfont from (1) requires type 
  1587         \ttfamily bool \normalfont while (2) wants to have \ttfamily (f\_f::real).
  1588         \normalfont Of course, we don't need \ttfamily rhs \normalfont anymore.
  1589       \item Type-checking can be very tedious. One might even inspect the
  1590         parse-tree of the program with {\sisac}'s specific debug tools:
  1591       \begin{verbatim}
  1592       val {scr = Prog t,...} = 
  1593         MethodC.from_store ["simplification",
  1594                  "of_rationals",
  1595                  "to_partial_fraction"];
  1596       atomty_thy @{theory "Inverse_Z_Transform"} t ;
  1597       \end{verbatim}
  1598       \item We check if the \textbf{semantics of the program} by stepwise evaluation
  1599         of the program. Evaluation is done by the Lucas-Interpreter, which works
  1600         using the knowledge in theory Isac_Knowledge; so we have to re-build Isac. And the
  1601         test are performed simplest in a file which is loaded with Isac.
  1602         See \ttfamily tests/../partial\_fractions.sml \normalfont.
  1603   \end{enumerate}
  1604 \<close>
  1605 
  1606 subsection \<open>Transfer to Inverse\_Z\_Transform.thy\<close>
  1607 text \<open>
  1608   It was not possible to complete this task, because we ran out of time.
  1609 \<close>
  1610 
  1611 
  1612 end
  1613