Welcome Guest! To enable all features please Login. New Registrations are disabled.

Notification

Icon
Error

Login


Options
Go to last post Go to first unread
Offline mkraska  
#1 Posted : 29 July 2017 01:05:44(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
I am trying to solve the problem that I can't overwrite special functions in the Maxima plugin via the IPluginLowLevelEvaluation.ExpressionEvaluation interface, see SS-2401.

Obviously one can add definitions to the canvas from within a plugin function execution using something like this:

Code:
Entry lhs = Entry.Create(TermsConverter.ToTerms("int(f,x,a,b)"));
Entry rhs = Entry.Create(TermsConverter.ToTerms("Int(f,x,a,b)")); ;
Entry def = context.AddDefinition(lhs, rhs);


This replaces the built-in definition of int(4) with the one provided by the maxima plugin in the current downstream canvas.

The above solution was found by blindly poking around, assisted by the Core doc.

Questions:

- Can I generate the definition directly from the text representations?
- How can I remove the definition?
- It seems that the variable names used in the definitions matter. int() does not provide the same results as Int() in some cases.
- What plugin might be a good source of inspiration for the above questions?

2017-07-29 00_02_39-Greenshot Editor.png
Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx

Wanna join the discussion?! Login to your SMath Studio Forum forum account. New Registrations are disabled.

Offline Davide Carpi  
#2 Posted : 29 July 2017 01:36:19(UTC)
Davide Carpi


Rank: Advanced Member

Groups: Registered, Advanced Member
Joined: 13/01/2012(UTC)
Posts: 2,647
Man
Italy
Location: Italy

Was thanked: 1329 time(s) in 875 post(s)
Good trick Good

Originally Posted by: mkraska Go to Quoted Post
- Can I generate the definition directly from the text representations?

You can split a plain text representation at the first definition symbol and generate the LHS & RHS parts; (C# string.Split() methods);

Originally Posted by: mkraska Go to Quoted Post
- How can I remove the definition?

Store.RemoveAt(), Store.removeRange() and Store.Clear() are the methods (last if you know the Definition, first two if you record where they were placed;

Originally Posted by: mkraska Go to Quoted Post
- It seems that the variable names used in the definitions matter. int() does not provide the same results as Int() in some cases.

I have to check.

Originally Posted by: mkraska Go to Quoted Post
- What plugin might be a good source of inspiration for the above questions?

probably the include plugin by Viacheslav
If you like my plugins consider to support SMath Studio buying a plan; to offer me a coffee: paypal.me/dcprojects
thanks 1 user thanked Davide Carpi for this useful post.
on 29/07/2017(UTC)
Offline Davide Carpi  
#3 Posted : 29 July 2017 02:32:40(UTC)
Davide Carpi


Rank: Advanced Member

Groups: Registered, Advanced Member
Joined: 13/01/2012(UTC)
Posts: 2,647
Man
Italy
Location: Italy

Was thanked: 1329 time(s) in 875 post(s)
Possible code:

Code:
Entry lhs = Entry.Create(TermsConverter.ToTerms("int(f,x,a,b)"));
Entry rhs = Entry.Create(TermsConverter.ToTerms("Int(f,x,a,b)")); ;
int index = context.Count;
Entry def = context.AddDefinition(lhs, rhs);

try
{
  // do your stuff here
}
catch
{
  // errors, they might happens
}
finally
{
  // remove the definition, even if an error occourred
  context.RemoveAt(index);
}
If you like my plugins consider to support SMath Studio buying a plan; to offer me a coffee: paypal.me/dcprojects
Offline mkraska  
#4 Posted : 29 July 2017 15:54:59(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
Thanks, Davide.

The include plugin has just one occurance of AddDefinition.

The idea is now to obtain the index of the definition using Store.Contains(Entry,Index) and remove it with RemoveAt()

As to the dependence on variable names: It was mitigated by also doing preprocessing for the integration variable in Int(4), otherwise parameter replacement didn't seem to work. Usually, the integration variable is just a dummy name and should not require preprocessing...

Is it sensible to use strange variable names like x__ in the definitions as it is sometimes on the canvas?

Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Offline Jean Giraud  
#5 Posted : 29 July 2017 18:47:22(UTC)
Jean Giraud

Rank: Guest

Groups: Registered
Joined: 04/07/2015(UTC)
Posts: 6,866
Canada

Was thanked: 981 time(s) in 809 post(s)
Personally, I like the way it was 5346 still 6179 latest release.

Integral Martin.PNG
Offline mkraska  
#6 Posted : 30 July 2017 02:52:21(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
I implemented a new MaximaTakeover() function, which adds definitions to the context or removes them according to the given arguments. First tests seem very promising, such that the full functionality of the Maxima plugin can be re-established soon.

It turned out that something like
Code:

int index;
if (context.Contains(lhs, out index) context.RemoveAt(index);

didn't do the job of deleting the definitions from the global context. The deletion actually worked (as per inspection in the debugger) but that was of only local scope. I had to resort to Clear().

Code:

        public static bool MaximaTakeoverF1(Term[][] args, ref Store context, ref Term[] result)
        {
            // List of available definitions
            String[] Functions = new String[]
            {
                "Diff(f__)",
                "Diff(f__,x__)",
                "Diff(f__,x__,n__)",
                "Int(f__,x__)",
                "Int(f__,x__,a__,b__)",
                "Lim(f__,x__,x0__)",
                "Sum(f__,var__,a__,b__)",
                "Det(m__)"
            };

            // Try to ensure maxima is running
            ControlObjects.CommunicationInterface.GetMaxima();
            // Check if Maxima is running and complain otherwise
            if (ControlObjects.CommunicationInterface.GetMaxima().GetState() != ControlObjects.CommunicationInterface.GetMaxima().GetMaximaStateRunning())
            {
                result = TermsConverter.ToTerms(ControlObjects.CommunicationInterface.GetMaxima().GetState());
                return true;
            }

            // normalize the arguments list to the first three characters of the string representation 
            // i.e. int, dif, lim,...
            List<string> NormArgs = new List<string>() { };
            foreach (Term[] arg in args)
            {
                string Arg = TermsConverter.ToString(arg);
                if (Arg.Length > 3) NormArgs.Add(Arg.Substring(1,3)); 
            }

            // Loop over the available functions
            string message = "";
            foreach (String Function in Functions)
            {
                string LhsString = Function.ToLower();
                Entry lhs = Entry.Create(TermsConverter.ToTerms(LhsString));

                if (NormArgs.Contains(LhsString.Substring(0, 3)) || NormArgs.Contains("all"))
                {
                    // add definition
                    Entry rhs = Entry.Create(TermsConverter.ToTerms(Function)); ;
                    Entry def = context.AddDefinition(lhs, rhs);
                    // augment message
                    string MsgPart = LhsString.Split('(')[0] + "(), ";
                    if (!message.Contains(MsgPart)) message += MsgPart;             
                }
                else
                {
                    // remove definition
                    context.Clear(lhs);
                }
            }

            // Make result string
            result = TermsConverter.ToTerms(Symbols.StringChar + message + Symbols.StringChar);
            return true;
        }
Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Offline mkraska  
#7 Posted : 30 July 2017 03:19:33(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
I like it this way...

Don't know, however, if it is safe to remove the ugly underscores from the variable names...

2017-07-30 02_14_18-SMath Studio 0.98.6398 - [Inttest.sm].png
Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Offline Jean Giraud  
#8 Posted : 31 July 2017 19:08:43(UTC)
Jean Giraud

Rank: Guest

Groups: Registered
Joined: 04/07/2015(UTC)
Posts: 6,866
Canada

Was thanked: 981 time(s) in 809 post(s)
Hello Martin,

Interesting, though the algo style is native in Smath 5346, 6179
except the first release 6179 is missing Int(2) [indefinite].
I think Sum will work as well, at least it was 5346.

Cheers, Jean

Maths Algo Style [Diff, Int].sm (16kb) downloaded 13 time(s).
Offline mkraska  
#9 Posted : 01 August 2017 17:26:43(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
I'd like to provide a standard description to the definitions created in MaximaTakeover().
Currently, the descriptions simply show the definition (as can be seen in the previous post).

The idea is, to get the description of the Maxima function (Int(...) and add it as description to the generated definitions, perhaps with some adjustments (convert uppercase to lowercase in function names).

How would I do that?


Code:

        public static bool MaximaTakeoverF(Term[][] args, ref Store context, ref Term[] result)
        {
            // List of available definitions
            String[] Functions = new String[]
            {
                "Diff(f__)",
                "Diff(f__,x__)",
                "Diff(f__,x__,n__)",
                "Int(f__,x__)",
                "Int(f__,x__,a__,b__)",
                "Lim(f__,x__,x0__)",
                "Sum(f__,var__,a__,b__)",
                "Det(m__)"
            };

            // Try to ensure maxima is running
            ControlObjects.CommunicationInterface.GetMaxima();
            // Check if Maxima is running and complain otherwise
            if (ControlObjects.CommunicationInterface.GetMaxima().GetState() != ControlObjects.CommunicationInterface.GetMaxima().GetMaximaStateRunning())
            {
                result = TermsConverter.ToTerms(ControlObjects.CommunicationInterface.GetMaxima().GetState());
                return true;
            }

            // Generate a string with all args concatenated
            var ArgString = ""; 
            foreach (Term[] arg in args) ArgString = ArgString + TermsConverter.ToString((Decision.Preprocessing(arg, ref context))); 

            // Loop over the available functions
            string message = "";
            foreach (String Function in Functions)
            {
                string LhsString = Function.ToLower();
                Entry lhs = Entry.Create(TermsConverter.ToTerms(LhsString));

                if (ArgString.Contains(LhsString.Substring(0, 3)) || ArgString.Contains("all"))
                {
                    // add definition
                    Entry rhs = Entry.Create(TermsConverter.ToTerms(Function));
                    Entry def = context.AddDefinition(lhs, rhs);
                    // augment message
                    string MsgPart = LhsString.Split('(')[0] + "(), ";
                    if (!message.Contains(MsgPart)) message += MsgPart;             
                }
                else
                {
                    // remove definition
                    context.Clear(lhs);
                }
            }

            // Make result string
            if (message.Length == 0) message = "All functions handled by SMath"; 
            else message = message.Substring(0, message.Length - 2) + " handled by Maxima";

            result = TermsConverter.ToTerms(Symbols.StringChar + message + Symbols.StringChar);
            return true;
        }
Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Offline Davide Carpi  
#10 Posted : 01 August 2017 20:23:20(UTC)
Davide Carpi


Rank: Advanced Member

Groups: Registered, Advanced Member
Joined: 13/01/2012(UTC)
Posts: 2,647
Man
Italy
Location: Italy

Was thanked: 1329 time(s) in 875 post(s)
You can use the AddDefinition(Definition value) method; Definition has some constructor with the description argument

Edited by user 01 August 2017 20:27:58(UTC)  | Reason: Not specified

If you like my plugins consider to support SMath Studio buying a plan; to offer me a coffee: paypal.me/dcprojects
thanks 1 user thanked Davide Carpi for this useful post.
on 02/08/2017(UTC)
Offline mkraska  
#11 Posted : 02 August 2017 02:06:09(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
Originally Posted by: Davide Carpi Go to Quoted Post
You can use the AddDefinition(Definition value) method; Definition has some constructor with the description argument


Thanks. Davide.
First, I tried a very compact way, but that didn't make it beyond the current math region.

Code:

                    // add definition
                    Entry rhs = Entry.Create(TermsConverter.ToTerms(Function));
                    context.AddDefinition(lhs, rhs);
                    // add description
                    context[context.Count-1].Description =  "description of "+ LhsString ;


Then I used the approach proposed by you, unfortunately, the definition constructor requires a terms list to specify the arguments. I found no smart way to extract this list from the function definition strings. Thus the code looks ugly and bloated.


Code:

                    string name = LhsString.Split('(')[0];
                    string[] vars = Regex.Replace(LhsString, @".+\((.+)\)", "$1").Split(',');
                    Term[] Tvars = new Term[1];
                    int i = 0;
                    foreach (string v in vars)
                    {
                        Tvars[i] = new Term(v, TermType.Operand, 0); i++;
                    }
                    context.AddDefinition(new Definition(name, Tvars, rhs, "description of "+name));
                    


This approach didn't work either, I even could not see the descriptions being generated at all in the debugger.

And in the end, when trying to provide a description in a math region directly, this is ignored. For the moment I have to give up. This might be related to the target functions being special functions. Re-definition somehow slips through, re-description obviously not.
2017-08-02 00_50_20-SMath Studio 0.98.6398 - [Takeovertest1.sm_].png

Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Offline Davide Carpi  
#12 Posted : 02 August 2017 10:53:58(UTC)
Davide Carpi


Rank: Advanced Member

Groups: Registered, Advanced Member
Joined: 13/01/2012(UTC)
Posts: 2,647
Man
Italy
Location: Italy

Was thanked: 1329 time(s) in 875 post(s)
Hello Martin,

Originally Posted by: mkraska Go to Quoted Post
This approach didn't work either, I even could not see the descriptions being generated at all in the debugger.


Confirmed. I've looked at the core code and I know why, I'll try to make ii possible.
If you like my plugins consider to support SMath Studio buying a plan; to offer me a coffee: paypal.me/dcprojects
Offline mkraska  
#13 Posted : 02 August 2017 13:26:29(UTC)
mkraska


Rank: Advanced Member

Groups: Registered
Joined: 15/04/2012(UTC)
Posts: 1,986
Germany

Was thanked: 1124 time(s) in 721 post(s)
Originally Posted by: Davide Carpi Go to Quoted Post
Confirmed. I've looked at the core code and I know why, I'll try to make ii possible.


Sounds promising. There is more to report.

Code:

context[context.Count-1].Description =  "description of "+ LhsString ;


This guy isn't just useless, it is also dangerous. It sweeps all but one signature variants for each function off the context. Just the versions with a single argument survive this seemingly harmless line of code.

BTW, working with the debugger and observing how the context changes during function calls provides great insight into how SMath works. It's real fun!
Martin Kraska

Pre-configured portable distribution of SMath Studio: https://smath.com/wiki/SMath_with_Plugins.ashx
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.