From: Albert Retey on 27 Apr 2010 04:06 Hi, > I would like to export rules from a package in such a way that the pattern > symbols did not include any contexts and in which I also did not have to > export the symbols used in the pattern. In addition, If possible, I would > like this to work even if the package was loaded from a notebook that had > something other than the Global` context. > > > > Here is a sample package and exported rule: > > > > BeginPackage["PackageContext`"]; > > > > Rule1::usage = "Rule1 is a test exported rule."; > > > > Begin["`Private`"]; > > > > Rule1 = Cos[x_]^2 + Sin[x_]^2 -> 1; > > > > End[]; > > > > EndPackage[]; > > > > Then, if we evaluate Rule1 we obtain a very clumsy version of the rule, > although I suppose it will work. > > > > Rule1 > > Cos[PackageContext`Private`x_]^2 + Sin[PackageContext`Private`x_]^2 -> 1 > > > > What I would like is the rule as written in the package. Is there a way to > do this? There is a problem with your expectation: I think every symbol is per definition in a context, so it is strictly not possible to define a symbol which "does not include a context". Whether you see the "clumsy version" or just the symbol name depends on whether the symbols context is part of $ContextPath at the time the output is shown or not. Considering this one way to achieve something that behaves as you probably want is this: Rule1 := Block @@ Join[ List /@ ToExpression["x", InputForm, Hold], Hold[(Cos[y_]^2 + Sin[y_]^2 -> 1) /. y -> Symbol["x"]] ] What this does is to create the symbol x not at the time the rule is defined but only when the rule is called. So it will create the symbol x in the context where Rule1 is used and hence should in all but very exotic cases be shown as just x without its context shown. Since you don't know the context where the x will be created it makes sense to ensure it will not cause problems if there are definitions for this new x. This makes the whole definition somewhat clumsy itself, but the user will usually not see it. The whole procedure is of course rather inefficient since it will run the above code every time you call it. I don't know if this is worth the advantage of a "nicer looking output" in your case, but depending on the purpose of the package efficiency might not be so crucial... hth, albert
From: Rui on 27 Apr 2010 07:40 On Apr 26, 5:51 am, "David Park" <djmp...(a)comcast.net> wrote: > I would like to export rules from a package in such a way that the pattern > symbols did not include any contexts and in which I also did not have to > export the symbols used in the pattern. In addition, If possible, I would > like this to work even if the package was loaded from a notebook that had > something other than the Global` context. > > Here is a sample package and exported rule: > > BeginPackage["PackageContext`"]; > > Rule1::usage = "Rule1 is a test exported rule."; > > Begin["`Private`"]; > > Rule1 = Cos[x_]^2 + Sin[x_]^2 -> 1; > > End[]; > > EndPackage[]; > > Then, if we evaluate Rule1 we obtain a very clumsy version of the rule, > although I suppose it will work. > > Rule1 > > Cos[PackageContext`Private`x_]^2 + Sin[PackageContext`Private`x_]^2 -> 1 > > What I would like is the rule as written in the package. Is there a way to > do this? > > David Park > > djmp...(a)comcast.net > > <http://home.comcast.net/~djmpark>http://home.comcast.net/~djmpark/ I'd try something like: BeginPackage["PackageContext`"]; Rule1::usage = "Rule1 is a test exported rule."; Begin["`Private`"]; Rule1 := (Cos[x_]^2 + Sin[x_]^2 -> 1)/.x->Unique["x"]; End[]; EndPackage[]; so you get something like Rule1 Cos[x1_]^2 + Sin[x1_]^2 -> 1 cause the symbol is created only when the Rule1 is evaluated
From: Rui on 28 Apr 2010 01:59 On Apr 27, 5:04 am, "David Park" <djmp...(a)comcast.net> wrote: > I want to thank Ingolf Dahl, Bob Hanlon and Patrick Scheibe for their > answers. Using the Global` context is a good solution, except if the package > had been loaded in something other than the Global` context, say on a > Function page. Also I would like to have a simple way to process simply > written rules in the package such that it would return simple looking and > usable rules to the user. > > There are a number of issues I would like to raise because I'm not certain > of the best procedure if we want a package to generate an expression with > new symbols that are in the Context of the notebook using the package. There > are two solutions that might be useful but are unavailable. > > 1) WRI might be able to create a floating context, which had the property > that it took on the context of the notebook or cell in which it is created. > This could then be used by package writers to return created symbols. > > 2) WRI might provide a way for a package routine to retrieve the current > Context in the InputNotebook[]. This could then be used actively in > generating new symbols. > > Otherwise we can obtain "Context free" output by putting the Rule symbols > into existing Contexts such as the Package Context itself, or the System` > context. But is it good practice to usurp simple symbols such as x, y, z > into some special Context? Maybe it is all right if users always read in the > package first. But suppose a number of packages start doing this? > > In any case, here is the package routine again in a form that statically > determines the Context at the time it is read in. The problem is that if the > user changes evaluation from one notebook to another, that have different > Contexts, then the package must be read in anew. I am taking advantage here > of the fact that SymbolName strips any leading Context from a symbol so we > can just attach the new Context. > > System`loadcontext=Context[]; > > BeginPackage["PackageContext`"]; > > Rule1::usage="Rule1 is a test exported rule."; > > Begin["`Private`"]; > > cs[var_Symbol]:=var->Symbol[System`loadcontext<>SymbolName[var]] > > cs[vars:{__Symbol}]:=cs/@vars > > Rule1=(y_ Sin[x_ y_]/;AtomQ[y]->{x,y})//.cs[{x,y}]; > > End[]; > > EndPackage[]; > > Test: > > Rule1 > a Sin[a b] /. Rule1 > > y_ Sin[x_ y_] /; AtomQ[y] -> {x, y} > {b, a} > > David Park > djmp...(a)comcast.nethttp://home.comcast.net/~djmpark/ > > From: David Park [mailto:djmp...(a)comcast.net] > > I would like to export rules from a package in such a way that the pattern > symbols did not include any contexts and in which I also did not have to > export the symbols used in the pattern. In addition, If possible, I would > like this to work even if the package was loaded from a notebook that had > something other than the Global` context. > > Here is a sample package and exported rule: > > BeginPackage["PackageContext`"]; > > Rule1::usage = "Rule1 is a test exported rule."; > > Begin["`Private`"]; > > Rule1 = Cos[x_]^2 + Sin[x_]^2 -> 1; > > End[]; > > EndPackage[]; > > Then, if we evaluate Rule1 we obtain a very clumsy version of the rule, > although I suppose it will work. > > Rule1 > > Cos[PackageContext`Private`x_]^2 + Sin[PackageContext`Private`x_]^2 -> 1 > > What I would like is the rule as written in the package. Is there a way to > do this? > > David Park > > djmp...(a)comcast.net > > <http://home.comcast.net/~djmpark>http://home.comcast.net/~djmpark/ David. I think you could do something like Symbol[$Context<>"x"] to make the symbol belong to the current context when the function is called. However, I guess it makes sense to put it inside a block if you want it for output and don't want conflics. I gotta go now, but I think it should be simple to make a function that behaves SymbolOut[{list of symbols}, expression] that treats every symbol inside the list of symbols as a symbol belonging to the context where it was evaluated, taking local values to prevent conflicts. I guess with a With to replace the symbols by Symbol[$Context<>ToString[symbolss]] and a Block to localize them it should be possible. I'll try it when I'm back.
From: David Park on 29 Apr 2010 02:51 Rui, That seems like a good solution. Many thanks for suggesting it. Here is a new test package. newsymbols will be a list of rules for all of the symbols used in exported rules. One precaution is that the definitions have to be delayed so that $Context is not evaluated in the package. This construction also works if one wishes to generate an expression in some variable and we wish to give the variable a default value. BeginPackage["PackageContext`"]; Rule1::usage="Rule1 is a test exported rule."; Routine1::usage="Routine1[] returns a test polynomial with a default variable x."; Begin["`Private`"]; newsymbols:={x->Symbol[$Context<>"x"],y->Symbol[$Context<>"y"]}; Rule1:=(y_ Sin[x_ y_]/;AtomQ[y]->{x,y})//.newsymbols; Routine1[x_:Automatic]:= Module[{var}, var=If[x===Automatic,Symbol[$Context<>"x"],x]; var+var^2]; End[]; EndPackage[]; Rule1 a Sin[a b] /. Rule1 Routine1[] I tested this with a PackageContext`m file, reading it in both in a regular Global` context notebook, and in a notebook with its own Notebook context. I could go back and forth and it evaluated properly in both notebooks and the x,y symbols were in their respective notebook contexts. Another solution for rules, suggested to me by Maxim Rytin, is to use Formal symbols: formalsymbols = {x -> \[FormalX], y -> \[FormalY]} Rules seem to be a proper place to use Formal symbols because they are never given values and being in the System` Context display without Context information. But these were introduced in Version 6 and may not be familiar to many users. They have gray dots above and below the characters. They are not suitable for default variables because we may wish to later give those values. David Park djmpark(a)comcast.net http://home.comcast.net/~djmpark/ From: Rui [mailto:rui.rojo(a)gmail.com] On Apr 27, 5:04 am, "David Park" <djmp...(a)comcast.net> wrote: > I want to thank Ingolf Dahl, Bob Hanlon and Patrick Scheibe for their > answers. Using the Global` context is a good solution, except if the package > had been loaded in something other than the Global` context, say on a > Function page. Also I would like to have a simple way to process simply > written rules in the package such that it would return simple looking and > usable rules to the user. > David. I think you could do something like Symbol[$Context<>"x"] to make the symbol belong to the current context when the function is called. However, I guess it makes sense to put it inside a block if you want it for output and don't want conflics. I gotta go now, but I think it should be simple to make a function that behaves SymbolOut[{list of symbols}, expression] that treats every symbol inside the list of symbols as a symbol belonging to the context where it was evaluated, taking local values to prevent conflicts. I guess with a With to replace the symbols by Symbol[$Context<>ToString[symbolss]] and a Block to localize them it should be possible. I'll try it when I'm back.
First
|
Prev
|
Pages: 1 2 Prev: Stop mathematica reordering expression during matrix Next: Precision of calculations |