• Aucun résultat trouvé

Headings of procedures and functions in the Mathematicasystem

Dans le document Extension of Mathematica systemfunctionality (Page 128-137)

Chapter 6. Problems of procedural programming in the Mathematicasoftware

6.4. Headings of procedures and functions in the Mathematicasystem

In many contexts, it is not necessary to know the exact value of an arbitrary expression; it suffices to know that the given expression belongs to a certain broad class, or group, of expressions which share some common properties. These classes or groups are known astypes. IfT represents a type, then an expression is of typeT if it belongs to the class thatT presents. For example, an expression is said to be of typeInteger if it belongs to the

definite class of expressions denoted by the type nameInteger, which is the set of integers.

Many procedures and functions use the types to direct the flow of control in algorithms or to decide whether an expression is a valid input. For example, the behavior of a function or a procedure generally depends on the types of its actual arguments. At that, the result of a number of operations is defined by type of their arguments. Thetype – fundamental concept of the theory of programming, defining an admissible set of values or operations which can be applied to such values and, perhaps, also a way of realization of storage of values and performance of operations.

Any objects with which the programs operate, belong to certain types. The concept of data type in programming languages of high level appeared as absolutely natural reflection of that fact that the data and expressions which are processed by a program can have various sets of admissible values, be stored in RAM of the computer in different ways, be

processed by different commands of the processor. At that, the type of any object can be defined in 2 ways, namely: by a set of all values belonging to this type, or by a certain predicate function defining object belonging to this type. Advantages from use of types of objects are reduced to three highlights:(1) protection against errors of assignment,

incorrect operations along with inadmissible factual arguments passed to a

procedure/function;(2) the standardization provided by agreements on the types supported by the majority of the programming systems,(3) documenting of software in many

respects becomes simpler at use of the standard typification of the objects and data used in them. In the modern languages of programming are used several systems of typification a brief characteristic of which can be found in [33] whereas more in detail it is possible to familiarize oneself with them in a number of books on modern programming systems.

Considering importance of typification of language objects, this aspect is considered by us and concerningMathematica system in books [28-33]. In particular, in our book [30]

enough in details from point of view of development of the mechanism of typification bothMathematica andMaple systems are considered as computer mathematics systems which are the most developed and popular for today.

Unlike 209 types, for example, of theMaple 11 which are tested by the`type`

procedure(apart from a considerable enough set of the user types connected to the Mapleby means of our library [47]), theMathematica 9 has only60 testingQ– functions whose names have the formNameQ, for example, callSyntaxQ[x] returnsTrue if the contents of stringx is a correctMathematica–expression, andFalse otherwise. In a certain measure to this function theToExpression function adjoins that evaluates all expressions which are in the argument of string format with return ofNull. By results of their

performance the given functions can be considered as testing tools of correctness of the expressions that are in a string. At that, if in the first case we receive value {True,False}, in the second case the correctness can be associated with return ofNull. In this context theToExpression function in a certain relation is similar to the `parse` procedure of

theMaple system [10,14-16,21,25-27]. If necessary, the user can also create own functions with names of the formNameQ which will significantly expand the range of similar

standard system tools. Below, this question largely is detailed on specific examples of such means.

Coding of definitions of types directly in headings of procedures/functions takes place only for theMathematica system, allowing in the call point of a procedure/function without execution of it and without appeal to external tools to execute testing for an admissibility of the actual arguments received by the procedure/function. Such approach increases efficiency of execution of a procedure/function, doing it by the more mobile.

The given approach is especially convenient in the case where the type posesses highly specialized character or its definition is described by small and a rather clear program code. Indeed, in a number of cases the inclusion of definitions of the testing means directly into headings is very conveniently. So, this approach is used rather widely in means from theAVZ_Package package [48]. In general, this approach allows to typify quite in details in many important applied data; its essence rather visually illustrates the following simple fragment, namely:

In[2524] := ArtKr[x_ /; {T[z_] := If[z <= 80 && z >= 8, True, False], T[x]}[[2]], y_ /;

StringQ[y] && ! SuffPref[y, {“avz”, “agn”, “vsv”}, 1]] := Module[{a = 72, b = 67}, y

<> ” = ” <> ToString[x + a + b]]

In[2525] := {T[6], Map7[ArtKr, Sequences, {{72, “h”}, {42, “j”}, {50, “avagvs”}}], T[6]}

Out[2525]= {T[6], {”h= 211“, “j= 181“, “avagvs= 189”}, False}

In[2526]:= Definition[T]

Out[2526]= T[z_]:= If[z<= 80&& z>= 8, True, False]

The example of simple ArtKr procedure of the modular type quite visually illustrates opportunities on the organization of typified testing of the actual arguments of the

procedure when definition of a typeT is given directly in heading of the procedure and is activated at once after the first call ofArtKr procedure. Many of means ofAVZ_Package package use similar approach in own organization [48].

On the assumption of the general definition of a procedure, in particular, of modular type M[x_/;Testx,y_/;Testy, …] := Module[{locals},Procedure body]

and of that fact that concrete definition of the procedure is identified not by itsname, but itsheading we will consider a set of the useful enough means which provide the various manipulations with headings of procedures and functions, and play a very important part in procedural programming and, first of all, programming of problems of the system

character. Having defined such object rather useful in many appendices as theheading of a procedure/function in the form”Name[The list of formal arguments with the testing means ascribed to them]“, quite naturally arises the question of the creation of means for a

testing of objects regarding their relation to the type `Heading`. It is possible to represent theHeadingQ procedure as a such tool whose source code with examples of its use is represented by the following fragment. The procedure callHeadingQ[x] returnsTrue if an objectx, given in string format, can be considered as a syntactic correct heading; otherwise False is returned; in case of inadmissible argumentx the callHeadingQ[x] is returned unevaluated. TheHeadingQ procedure is rather essentially used in a series of means from theAVZ_Package package [48].

In[3385]:= HeadingQ[x_ /; StringQ[x]] := Module[{a, b, c, k = 1, m = True, n = True}, If[StringTake[x, {–1,–1}] == “]” &&

StringCount[x, {“[“, “]”}] == 2 && ! StringFreeQ[StringReplace[x, ” “–> ””], “[]”], Return[m], If[! StringFreeQ[RedSymbStr[x, “_”, “_”], “[_]”], Return[! m]]];

Quiet[Check[ToExpression[x], Return[False]]];

If[DeleteDuplicates[Map3[StringFreeQ, x, {“[“, “]”}]] === {False}, c =

StringPosition[x, “[“][[1]][[2]]; If[c == 1, Return[False], a = StringTake[x, {c,–1}]], Return[False]]; b = StringPosition[a, “[“][[1]][[1]]; c = StringPosition[a, “]”][[–1]]

[[1]]; a = “{” <> StringTake[a, {b + 1, c–1}] <> “}“; a = Map[ToString, ToExpression[a]];

If[DeleteDuplicates[Mapp[StringFreeQ, a, “_”]] =={False}, Return[True]]; If[{c, a}== {2, {}}, Return[True], If[a == {}|| StringTake[a[[1]], {1, 1}] == “_”,

Return[False], For[k, k <= Length[a], k++, b = a[[k]];

If[StringReplace[b, “_”–> ””] != ”” && StringTake[b, {–1,–1}] == “_” || !

StringFreeQ[b, “_ “] || ! StringFreeQ[b, “_:”]||! StringFreeQ[b, “_.”], m = True, n =

False]]]; m && n]]

In[3386] := {HeadingQ[“D[x_, y_/; ListQ[y], z_:75, h_]”], HeadingQ[“D[x_, y_, z_:75, h_]”],

HeadingQ[“D[x_, y_/; ListQ[y], z_:75, _]”]}

Out[3386]= {True, True, True}

In[3387]= {HeadingQ[“D[x_, y_/; ListQ[y], z_:75, h]”], HeadingQ[“[x_, y_/; ListQ[y], z:75]”] }

Out[3387]= {False, False}

In[3388]:= {HeadingQ[“g[]”], HeadingQ[“t[x__]”], HeadingQ[“p[x__]”], HeadingQ[“h[_]”] }

Out[3388]= {True, True, True, False}

In[3389]:= {HeadingQ[“D[_, x_]”], HeadingQ[“Z[x__]”], HeadingQ[“Q[x___]”]}

Out[3389]= {True, True, True}

In[3390] := {HeadingQ[“D[x_, y_/; ListQ[y], z_:75, h]”], HeadingQ[“V[x_, y_/;ListQ[y], z_.]”]}

Out[3390]= {False, True}

At that, the given procedure along with standard means uses and our means such

asRedSymbStr, Map3 andMapp which are considered in the present book and in [28-33].

The procedure is represented as a rather useful means, first of all, in system programming, for example, at testing of objects types in definitions of procedures and functions similarly to the meansHead1 and Head2, considered in the present book too.

The followingHeadingQ1 procedure represents a very useful expansion of the

aboveHeadingQ procedure concerning its opportunity of testing of the headings onto their correctness. The procedure callHeadingQ1[x] returns True if the actual argumentx, given in string format, can be considered as a syntactically correct heading; otherwiseFalse is returned. The next fragment represents source code of theHeadingQ1 procedure and examples of its use.

In[2512] := HeadingQ1[x_ /; StringQ[x]] := Module[{b, c = {}, d, h = “F”, k = 1, a = Quiet[StringTake[x, {Flatten[StringPosition[x, “[“, 1]][[1]]+ 1,–2}]]},

If[StringFreeQ[x, “[“], False, b = StringSplit1[a, “,”]; For[k, k <= Length[b], k++, d

= b[[k]]; c = Append[c, If[StringFreeQ[d, “_”], False, If[MemberQ[ToString /@

{Complex, Integer, List, Rational, Real, String, Symbol}, StringTake[d,

{Flatten[StringPosition[d, “_”]][[–1]] + 1,–1}]], True, HeadingQ[h <> “[” <> d <>

“]”]]]]]; If[DeleteDuplicates[c] == {True}, True, False]]]

In[2513] := Map[HeadingQ1, {“H[s_String,x_/;StringQ[x],y_]”,

“T[x_,y_/;ListQ[y],z_List]”,

“V[x_, y_/; ListQ[y]&&Length[L] == 90]”, “E[x__, y_/; ListQ[y], z___]”}]

Out[2513] = {True, True, True, True}

In[2514]:= {Map[HeadingQ, {“H[s_Integer]”, “G[n_Integer,L_List]”,

“G[n___Integer]”}], Map[HeadingQ1, {“H[s_Integer]”, “G[n_Integer,L_List]”,

“G[n___Integer]”}]}

Out[2514]= {{True, True, True}, {True, True, True}}

In addition to the system means theHeadingQ1 procedure uses procedure StringSplit1 that represents an useful generalization of the system function StringSplit. It should be noted that regardless of the correct testing of quite wide type of headings, meanwhile, the procedureHeadingQ along with the HeadingQ1 not has comprehensive character because of a series of features of syntactical control ofMath–language. That the following simple example very visually illustrates, from which follows, that the system testing means perceive incorrect headings as correct expressions.

In[2567] := ToExpression[“W[x__/;_StringQ[x]]”]

Out[2567]= W[x__/; _StringQ[x]]

In[2568]:= SyntaxQ[“W[x__/;_StringQ[x]]”]

Out[2568]= True

At the same time two these procedures are rather useful in many cases. Meanwhile, on the basis of ourArgsTypes procedure serving for testing of formal arguments of a

function/procedure which has been activated in the current session perhaps further expansion of the testing opportunities of the HeadingQ1, allowing in certain cases to expand types of the correctly tested headings of procedures/functions. Meanwhile, here it is possible to tell only about expansion of opportunities at certain cases, but not about expansion as a whole. The fragment below represents source code of theHeadingQ2 procedure along with the most typical examples of its usage.

In[2942]:= HeadingQ2[x_ /; StringQ[x]] :=

Module[ {a, b, c, d = ToString[Unique[“agn”]]}, {a, b}= Map[DeleteDuplicates, Map[Flatten, Map3[StringPosition, x, {“[“, “]”}]]]; If[StringLength[x] == b[[–1]]

&& SymbolQ[c = StringTake[x, {1, a[[1]]–1}]], Quiet[Check[ToExpression[

StringReplace[x, c <> “[” –> d <> “[“, 1] <> ” := 72”], False]]; c = Map[SyntaxQ, ArgsTypes[d]]; ToExpression[“Remove[” <> d <> “]”]; If[DeleteDuplicates[c] ===

{True}, True, False], False]]

In[2943]:= Map8[HeadingQ1, HeadingQ2, {“V[x__/_String]”}]

Out[2943] = {True, False}

In[2944]:= Map8[HeadingQ1, HeadingQ2, {“V[x_/; StringQ[x]]”}] Out[2944]= {True, True}

In[2945]:= Map[HeadingQ2, {“F[x_/; StringQ[x]]”, “F[x/; StringQ[x]]”,

“F[x; StringQ[x]]”, “F[x_ /_ StringQ[x]]”, “F[x_//; StringQ[x]]”, “F[x_; y_; z_]”}]

Out[2945]= {True, True, True, False, False, True}

In[2946]:= Map[HeadingQ1, {“F[x_/; StringQ[x]]”, “F[x/; StringQ[x]]”,

“F[x; StringQ[x]]”, “F[x_/_ StringQ[x]]”,

“F[x_//; StringQ[x]]”, “F[x_; y_; z_]”}] Out[2946]= {True, False, False, True, False, True}

In[2947]:= Map[HeadingQ, {“F[x_/; StringQ[x]]”, “F[x/; StringQ[x]]”, “F[x;

StringQ[x]]”, “F[x_/_ StringQ[x]]”, “F[x_//; StringQ[x]]”, “F[x_; y_; z_]”}]

Out[2947]= {True, False, False, True, False, True}

In[2948]:= Map[#[“F[x_/_ StringQ[x]]”] &, {HeadingQ, HeadingQ1}] Out[2948]=

{True, True}

In[2949]:= Map[#[“F[x_/_ StringQ[x]]”] &, {HeadingQ2, HeadingQ3}] Out[2949]=

{False, False}

In[2950]:= Map[#[“F[x_/_StringQ[x]]”] &, {HeadingQ, HeadingQ1}] Out[2950]=

{True, True}

In[2951]:= Map[#[“F[x_/_StringQ[x]]”] &, {HeadingQ2, HeadingQ3}] Out[2951]=

{False, False}

Analogously to the procedures HeadingQ andHeadingQ1, the procedure

callHeadingQ2[x] returnsTrue if actual argumentx, set in string format, can be considered as a syntactically correct heading; otherwiseFalse is returned. At that, the examples

presented in the above fragment of applications of the proceduresHeadingQ, HeadingQ1 andHeadingQ2 quite visually illustrate distinctions between their functionality. The group of these means includes also theHeadingQ3 procedure that in the functional relation is equivalent to theHeadingQ2 procedure; its callHeadingQ3[x] returnsTrue if an actual argumentx, set in string format, can be considered as a syntactically correct heading;

otherwise, the call returnsFalse. At the same time between pairs of procedures

{HeadingQ[x],HeadingQ1[x]}& {HeadingQ2[x],HeadingQ3[x]} principal distinctions exist, in particular, on the headings {F[x_/_StringQ[x]], F[x_ / _StringQ[x]} the first pair returnsTrue while the second pair returns False as a quite visually illustrates the above fragment. It is also necessary to note that the first pair of testing functions is more high–speed what is very essential at their use in real programming. Meanwhile,

considering similar and some other unlikely encoding formats of the headings of functions and procedures, the represented four proceduresHeadingQ[x], HeadingQ1[x],

HeadingQ2[x] andHeadingQ3[x] can be considered as rather useful testing means in modular programming. At that, from experience of their use and their temporary characteristics it became clear that it is quite enough to be limited oneself only by

proceduresHeadingQ[x], HeadingQ1[x] that cover rather wide range of erroneous coding of the headings. Furthermore, taking into account the mechanism ofparse of expressions for their correctness that theMathematica system uses, creation of comprehensive tools of testing of the headings is very unlikely. Naturally, it is possible to use non–standard

receptions for receiving the testing means for the headings having a rather wide set of deviations from the standard, however such outlay do not pay off by the received benefits.

The following procedure serves as an useful enough means at manipulating with

procedures and functions, its callHeadPF[x] returns heading in string format of a block, module or function with a namex activated in the current session, i.e. of function in its traditional understanding with heading. While on other values of argumentx the call is returned unevaluated. Meanwhile, the problem of definition of headings is actual also in the case of the objects of the above type of the same name which have more than one heading. In this case the procedure callHeadPF[w] returns the list of headings in string format of the subobjects composing an objectw as a whole. The following fragment represents source code of theHeadPF procedure along with the most typical examples of its usage.

In[2942] := HeadPF[x_ /; BlockFuncModQ[x]] := Module[{b, c= ToString[x], a = Select[Flatten[{PureDefinition[x]}], ! SuffPref[#, “Default[“, 1] &]}, b =

Map[StringTake[#, {1, Flatten[StringPosition[#, {” := “, ” = “}]][[1]]–1}] &, a];

If[Length[b] == 1, b[[1]], b]]

In[2943]:= G[x_, y_] := x*Sin[y] + y*Cos[x]; s[] := 90*x; g := 500 In[2944]:=

Map[HeadPF, {G, s, Sin, 2015, g}]

Out[2944] = {”G[x_, y_]“, “s[]“,HeadPF[Sin], HeadPF[2015], HeadPF[500]} In[2945]:=

Map[HeadPF, {If, Tan, Log, True, G, “Infinity”, For, Do, ProcQ}] Out[2945]=

{HeadPF[If], HeadPF[Tan], HeadPF[Log], HeadPF[True],

“ G[x_, y_]“, HeadPF[”Infinity”], HeadPF[For], HeadPF[Do], “ProcQ[x_]”} In[2946]:=

M[x_ /; x == “avzagn”] := Module[{a}, a*x]; M[x_, y_, z_] := x*y*z; M[x_ /;

IntegerQ[x], y_String] := Module[{a, b, c}, x]; M[x_String] := x; M[x_, y_] :=

Module[{a, b, c}, “abc”; x + y]; In[2947]:= HeadPF[M]

Out[2947]= {”M[x_ /; x== "avzagn"]“, “M[x_, y_, z_]“,

“M[x_ /; IntegerQ[x], y_String]“, “M[x_String]“, “M[x_, y_]”}

So, the call HeadPF[x] returns the heading in string format of an object with a namex of the type {block,function,module} which has been activated in the current session. At that, for an objectx which has several various headings, the callHeadPF[x] returns the list of the headings whose order fully meets the order of the definitions returned by the function callDefinition[x]. In this regard testing of an objectx regarding to be of the same name is enough actually; theQmultiplePF procedure solves the problem whose source code along with typical examples of its usage the following fragment represents.

In[2780]:= QmultiplePF[x_, y___] :=

Module[{a = Flatten[{PureDefinition[x]}]}, If[MemberQ[{{“System”}, {$Failed}}, a], False, If[{y}!= {}&& ! HowAct[y], y = If[Length[a] == 1, a[[1]], a]]; True]]

In[2781] := M[x_ /; x == “avzagn”] := Module[{a, b, c}, x]; M[x_String] := x; M[x_, y_, z_] := x*y*z; M[x_List, y_] := Block[{a}, Length[x] + y] M[x_ /; IntegerQ[x], y_String] := Module[{a, b, c}, x]; M[x_, y_] := Module[{a, b, c}, “abc”; x + y];

In[2782]:= QmultiplePF[M]

Out[2782] = True

In[2783]:= {QmultiplePF[M, s], s}

Out[2783]= {True, {”M[x_ /; x== "avzagn"]:= Module[{a, b, c}, x]“,

“ M[x_String]:= x“, “M[x_, y_, z_]:= x*y*z“, “M[x_List, y_]:= Block[{a, b, c}, "abc";

Length[x]+ y]“, “M[x_ /; IntegerQ[x], y_String]:= Module[{a, b, c}, x]“, “M[x_, y_]:=

Module[{a, b, c}, "abc"; x+ y]”}}

In[2784] := Map[QmultiplePF, {M, 90, Avz, Sin, If, a + b}]

Out[2784]= {True, False, False, False, False, False}

The procedure callQmultiplePF[x] returnsTrue, ifx – an object of the same name(block,function,module), andFalse otherwise. While the procedure call

QmultiplePF[x,y] with the2nd optional argumenty –an indefinite variable– returns throughy the list of definitions of all subobjects with a namex. The QmultiplePF

procedure realization significantly uses the earlier considered PureDefinition procedure, and also ourHowAct function. In a number of cases theQmultiplePF procedure despite the relative simplicity is a rather convenient means at testing of objects of the specified types.

At testing of objects often arises necessity of allotment among them of the system

functions; this problem is solved by simple function, whose the call SystemQ[x]

returnsTrue if an objectx is a system function, i.e. is defined by builtin language of

theMathematica,andFalse otherwise. The function very simply is defined directly on the basis of the standard functionsDefinition, Names andToString. The following fragment represents source code of the SystemQ function with typical examples of its application.

In a number of appendices the given function represents quite certain interest and, first of all, giving opportunity quite effectively to differentiate means.

In[2975]:= SystemQ[S_] := If[Off[Definition::ssle];

! ToString[Definition[S]] === Null && MemberQ[Names[“System`*”], ToString[S]], On[Definition::ssle]; True, On[Definition::ssle]; False]

In[2976] := Map[SystemQ, {90, G, Sin, Do, While, False, ProcQ, a/b^2, M}]

Out[2976]= {False, False, True, True, True, True, False, False, False} Above all,

theSystemQ function is often used in the headings of procedures and functions, testing the actual arguments for admissibility. In addition to theSystemQ function it makes sense to present an useful enough function whose callLangHoldFuncQ[x] returnsTrue ifx – a basic function ofMath– language, andFalse otherwise. At that, underbasic function is understood a system function with one of the attributes ascribed to it, namely:HoldFirst, HoldAll orHoldRest. The function is represented as a quite useful means in the case of necessity of more accurate differentiation of software. The next fragment represents

source code of theLangHoldFunc function along with examples of its most typical usage.

In[2299]:= LangHoldFuncQ[x_] := If[SystemQ[x] &&

Intersection[Quiet[Check[Attributes[x], False]], {HoldAll, HoldFirst, HoldRest}] !=

{}, True, False]

In[2300] := Map[LangHoldFuncQ, {If, Goto, Do, Sin, Rule, Break, While, Switch, Which, For}]

Out[2300]= {True, False, True, False, False, False, True, True, True, True}

For a series of problems of system character the LangHoldFuncQ function allows to differentiate the set of all system functions of theMath–language according to the specified feature.

Right there pertinently to note some more means linked with the HeadPF procedure. So, theHeadings procedure– an useful enough expansion of the HeadPF procedure in the case of the blocks/functions/modules of the same name but with various headings.

Generally the callHeadings[x] returns the nested list whose elements are the sublists defining respectively headings of subobjects composing an objectx; thefirst elements of such sublists defines the types of subobjects whereas others define theheadings

corresponding to them. The next fragment represents source code of theHeadings procedure along with the most typical examples of its usage.

In[2385] := Headings[x_ /; BlockFuncModQ[x]] := Module[{n, d, h, p, t, k =1, c = {{“Block”}, {“Function”}, {“Module”}}, a = Flatten[{PureDefinition[x]}]}, While[k

<= Length[a], d = a[[k]]; n = ToString[Unique[“agn”]]; ToExpression[n <> d];

ClearAll[p]; h = HeadPF[t = n <> ToString[x]]; d = StringTake[h, {StringLength[n] + 1, –1}]; BlockFuncModQ[t, p]; If[p == “Block”, AppendTo[c[[1]], d], If[p ==

“Function”, AppendTo[c[[2]], d], AppendTo[c[[3]], d]]]; ToExpression[“Remove[” <>

t <> “,” <> n <> “]”]; k++]; c = Select[c, Length[#] > 1 &]; If[Length[c] == 1, c[[1]], c]] In[2386]:= M[x_ /; SameQ[x, “avz”], y_] := Module[{a, b, c}, y]; M[x_, y_, z_] := x + y + z; L1[x_, y_] := Block[{a, b, c}, x + y];

M[x_ /; x == “avz”] := Module[{a, b, c}, x]; L[x_] := x; M[x_ /; IntegerQ[x], y_String] := Module[{a, b, c}, x]; M[x_, y_] := Module[{a, b, c}, “agn”; x + y];

M[x_String] := x; M[x_ /; ListQ[x], y_] := Block[{a, b, c}, “agn”; Length[x] + y];

In[2387]:= Headings[M]

Out[2387]= {{”Block“, “M[x_ /; ListQ[x], y_]”}, {”Function“, “M[x_, y_, z_]“,

“ M[x_String]”}, {”Module“, “M[x_ /; x=== "avz", y_]“, “M[x_ /; x== "avz"]“, “M[x_

/; IntegerQ[x], y_String]“, “M[x_, y_]”}} In[2388]:= V1[x_] = x; Map[Headings, {L, L1, 80, Sin, agn, V1}] Out[2388]= {{”Function“, “L[x_]”}, {”Block“, “L1[x_, y_]”}, Headings[80],

Headings[Sin] , Headings[agn], {”Function“, “V1[x_]”}} In[2389]:= G[x_] := x;

Headings[G]

Out[2389]= {”Function“, “G[x_]”}

In[2390]:= h = 80; P[x_] := Module[{a = 80, b = 480}, h = (a + b)*x; h^2];

{Headings[P], h}

Out[2390]= {{”Module“, “P[x_]”}, 80}

On x arguments different from the block/function/module, the procedure callHeadings[x]

is returned unevaluated. This tool is of interest, first of all, from the programmer standpoint. In a number of the appendices which use the procedural programming,

theHeadings procedure is useful enough. At that, the given procedure along with standard means uses and our means such asBlockFuncModQ, PureDefinition andHeadPF that are considered in the present book and in [28-33]. Examples of the previous fragment very visually illustrate structure of the results returned by the given procedure.

In a number of the appendices which widely use procedural programming, a rather useful is theHeadingsPF procedure which is an expansion of the previous procedure. Generally the procedure callHeadingsPF[] returns the nested list, whose elements are the sublists defining respectively headings of functions, blocks and modules whose definitions have been evaluated in the current session; the first element of each such sublist defines an object type in the context of {”Block“,”Module“, “Function”} while the others define the headings corresponding to it. The procedure call returns thesimple list if any of sublists doesn’t contain headings; at that, if in the current session the evaluations of definitions of objects of thespecified three types weren’t made, the procedure call returns theempty list.

At that, the procedure call with any arguments is returned unevaluated. The fragment below represents source code of theHeadingsPF procedure along with examples of its typical usage.

In[2913] := HeadingsPF[x___ /; SameQ[x, {}]] := Module[{a = {}, d = {}, k = 1, b, c = {{“Block”}, {“Function”}, {“Module”}}, t},

Map[If[Quiet[Check[BlockFuncModQ[#], False]], AppendTo[a, #], Null] &, Names[“`*”]]; b = Map[Headings[#] &, a]; While[k <= Length[b], t = b[[k]];

If[NestListQ[t], d = Join[d, t], AppendTo[d, t]]; k++]; Map[If[#[[1]] == “Block”, c[[1]] = Join[c[[1]], #[[2 ;; –1]]], If[#[[1]] == “Function”, c[[2]] = Join[c[[2]], #[[2 ;; –

1]]], c[[3]] = Join[c[[3]], #[[2 ;; –1]]]]] &, d]; Select[c, Length[#] > 1&]’ If[Length[c]

== 1, c[[1]], c]]

In[2914] := M[x_ /; SameQ[x, “avz”], y_] := Module[{a, b, c}, y]; L1[x_] := x; M[x_, y_, z_] := x + y + z; L[x_, y_] := x + y;

M[x_ /; x == “avz”] := Module[{a, b, c}, x];

M[x_ /; IntegerQ[x], y_String] := Module[{a, b, c}, x]; M[x_, y_] := Module[{a, b, c},

“agn”; x + y]; M[x_String] := x; M[x_ /; ListQ[x], y_] := Block[{a, b, c}, “agn”;

Length[x] + y];

F[x_ /; SameQ[x, “avz”], y_] := {x, y}; F[x_ /; x == “avz”] := x In[2915]:=

HeadingsPF[]

Out[2915]= {{”Block“, “M[x_ /; ListQ[x], y_]”},

{ “Function“, “F[x_/; x=== "avz", y_]“, “F[x_/; x== "avz"]“, “L[x_, y_]“, “L1[x_]“,

“M[x_, y_, z_]“, “M[x_String]”},

{”Module“, “M[x_ /; x=== "avz", y_]“, “M[x_, y_]“,

“M[x_ /; x== "avz"]“, “M[x_ /; IntegerQ[x], y_String]”}}

Reloading of the system without activation of the user means of the specified

Dans le document Extension of Mathematica systemfunctionality (Page 128-137)