Skip to content

Commit

Permalink
paclet: 0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
asdasd1dsadsa committed Nov 21, 2022
1 parent 44cc9fb commit 75741bf
Show file tree
Hide file tree
Showing 13 changed files with 417 additions and 1 deletion.
19 changes: 19 additions & 0 deletions PackPaclet.wls
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env wolframscript
(* ::Package:: *)

SetDirectory@If[$Notebooks, NotebookDirectory[], Directory[]]


paclet = CreatePacletArchive["RubiSteps", "Paclets"]


PacletManager`BuildPacletSiteFiles@Directory[]


PacletInstall["Paclets/RubiSteps-0.0.1.paclet", ForceVersionInstall -> True]


<< RubiSteps`


ResetDirectory[]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes.
1 change: 1 addition & 0 deletions PacletSite.m
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PacletSite[Paclet["Name" -> "RubiSteps", "Version" -> "0.0.1", "WolframVersion" -> "12.2+", "Description" -> "Enhancement for Rubi steps.", "Root" -> ".", "Loading" -> "Manual", "Extensions" -> {{"Kernel", "Root" -> ".", "Context" -> "RubiSteps`"}}]]
Binary file added PacletSite.mz
Binary file not shown.
Binary file added Paclets/RubiSteps-0.0.1.paclet
Binary file not shown.
38 changes: 37 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
@@ -1,2 +1,38 @@
[![View notebooks](https://wolfr.am/HAAhzkRq)](https://wolfr.am/Tf0XqiXI)
![](/README.PNG)
![](/Package/README.PNG)

# Installation

## Old-fashion package file

You can execute [this script](/Package/Install.wls) to install [the package file](/Package/RubiSteps.wl), manually also OK.

Note:

* The picture above illustrates this version, not the following paclet version.

* No longer maintained.

## New Paclet

Evaluate the following in Wolfram kernel to install:

`PacletInstall["RubiSteps", "Site" -> "https://github.com/asdasd1dsadsa/RubiSteps/raw/master"]`

**If** not having a good Internet, try to get the latest paclet file from [here](/Paclets/), and then evaluate:

`PacletInstall["the/path/to/the/file.paclet"]`

Note:

* Perhaps I won't update this too, but at least I intend to.

* Function usage changed. Not same to the old-fashion one.

* Requires Wolfram Kernel with 12.2+ version.

---

# ToDo

* Parentheses for preventing $ax+bx^2--cx^3$ 。
325 changes: 325 additions & 0 deletions RubiSteps/Kernel/RubiSteps.wl
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
(* ::Package:: *)

(* ::Title:: *)
(*RubiSteps*)


(* ::Chapter:: *)
(*Begin*)


BeginPackage["RubiSteps`", {"Rubi`"}]


ClearAll@"`*"


ShowIntSteps
RiffleTeXForm
TeXIntSteps


SubstitutionInformation


Begin["`Private`"]


ClearAll@"`*"


(* ::Chapter:: *)
(*Definition*)


ShowIntSteps::usage = ShowIntSteps::usage::English =
"ShowIntSteps[\!\(\*StyleBox[\"expr\", \"TI\"]\), \!\(\*StyleBox[\"var\", \"TI\"]\), \!\(\*StyleBox[\"opts\", \"TI\"]\)]\nShow steps of integration of \!\(\*StyleBox[\"expr\", \"TI\"]\) over \!\(\*StyleBox[\"var\", \"TI\"]\).\n\nUse ShowIntSteps[\"OptionList\"] to see the list of option keys and values."


ShowIntSteps::usage::ChineseSimplified =
"ShowIntSteps[\!\(\*StyleBox[\"expr\", \"TI\"]\), \!\(\*StyleBox[\"var\", \"TI\"]\), \!\(\*StyleBox[\"opts\", \"TI\"]\)]\n\:5c55\:793a\!\(\*StyleBox[\"expr\", \"TI\"]\)\:5bf9\!\(\*StyleBox[\"var\", \"TI\"]\)\:7684\:79ef\:5206\:7684\:6b65\:9aa4\:3002\n\n\:7528 ShowIntSteps[\"OptionList\"] \:6765\:4e86\:89e3\:9009\:9879\:7684\:53ef\:80fd\:8bbe\:7f6e\:3002"


RiffleTeXForm::usage = RiffleTeXForm::usage::English =
"RiffleTeXForm[\!\(\*StyleBox[\"header\", \"TI\"]\)][\!\(\*StyleBox[\"list\", \"TI\"]\)] constructs an aligned equation."


SubstitutionInformation::usage = SubstitutionInformation::usage::English =
"SubstitutionInformation represents substitution rules for expressions. SubstitutionInformation is also an option of ShowIntSteps."


TeXIntSteps::usage = TeXIntSteps::usage::English =
"TeXIntSteps[\!\(\*StyleBox[\"expr\", \"TI\"]\), \!\(\*StyleBox[\"var\", \"TI\"]\), \!\(\*StyleBox[\"opts\", \"TI\"]\)]\nCall MaTeX for rendering steps of integration of \!\(\*StyleBox[\"expr\", \"TI\"]\) over \!\(\*StyleBox[\"var\", \"TI\"]\).\n\nOptions will be passed to MaTeX."


(* ::Section:: *)
(*ShowIntSteps*)


(* ::Subsection::Closed:: *)
(*Evaluation*)


evaluateOnce = ReleaseHold@ReplaceAll[HoldComplete@#, Defer[h:Rubi`Int|Rubi`Subst|Rubi`Dist] :> h] &;


sowAndReturn = (
Sow[evaluateOnce@HoldForm@#, RubiStepTag];
evaluateOnce@#
) &;


(* ::Text:: *)
(*Create new symbols as substituted variables and forbid substitutions to be performed.*)


ForbidSubstitution[newVariableGenerator_][input_] :=
input //. Defer[Rubi`Subst][expr_, src_, tar_] :> (NewSubstitution[expr /. src -> #, #, tar]&@newVariableGenerator@src) //With[
{
equivalentClasses = Map[First, GatherBy[
Cases[input, NewSubstitution[_, src_, tar_] :> {src, tar}, Infinity]
, Last], {2}]
},
# /. Catenate[Thread[Rest@#->First@#] & /@ equivalentClasses]
] &


(* ::Text:: *)
(*For "SubstitutionInformation" -> Automatic , only new substitutions will be displayed.*)


FromNewToOld[input_] := input /. NewSubstitution -> OldSubstitution


PerformSubstitution[input_] := input //.
(NewSubstitution|OldSubstitution)[expr_?(FreeQ[NewSubstitution|OldSubstitution]), src_, tar_] :> (expr /. src -> tar)
(* The `FreeQ` works for `GeneratedParameters -> Identity`. *)


(* ::Subsection::Closed:: *)
(*Output Conversion*)


CatenateReapWithSimplify[compfunc_][{result_, sow_}] := Flatten[sow, 1] // Append[
If[compfunc === None,
result,
Quiet[
Simplify[result, ComplexityFunction -> compfunc, TimeConstraint -> 10]
, Simplify::time]
] // HoldForm@#& (* This `HoldForm` works for `DeleteDuplicates` *)
]


ReplaceGeneratedSymbol::toomuchvar = "Method \"SingleLetter\" does not have enough free single-letter symbols as `1` symbols are needed. Original unique symbols is returned instead.";


ReplaceGeneratedSymbol[input_, toBeReplace_, appearedSymbols_, method_] := Switch[method,
Automatic|"SingleLetter",
With[{
generatedParameters = Quiet[
Take[#, Length@toBeReplace]&@Cases[Symbol /@ #, _Symbol]&@Complement[
CharacterRange["a", "z"],
SymbolName/@appearedSymbols,
{"d", "e", "i", "j", "o"} (* Escape \[DifferentialD], \[ExponentialE], \[ImaginaryI], \[ImaginaryJ], O *)
]
, Take::take]
}, If[ListQ@generatedParameters,
input /. MapThread[Rule, {toBeReplace, generatedParameters}],
Message[ReplaceGeneratedSymbol::toomuchvar, Length@toBeReplace];input
] ],
Identity|"Identity"|None|False,
input,
Unique|"Unique",
ReplaceAll[input,
s_Symbol :> RuleCondition[(* Undocumented function `RuleCondition` used for invoking evaluation before replacing*)
If[Length@#===1,
s,
Subscript[
ToExpression@StringRiffle[Most@#, "$"],
ToExpression@Last@#
]
] &@StringSplit[SymbolName@s, "$"]
]
],
_,
input /. MapThread[Rule, {toBeReplace, Array[method, Length@toBeReplace]}]
]


ExtractSubstitutionInformation[steps_List] := With[{substRules = Cases[#, NewSubstitution[_, src_, tar_] :> {src, tar}, Infinity]},
SubstitutionInformation[# //. (NewSubstitution|OldSubstitution)[expr_, _, _] :> expr, substRules]
] & /@ steps


RiffleTeXForm[header_][steps_] := StringRiffle[{"\\begin{aligned}",
Convert`TeX`ExpressionToTeX@header,
Sequence@@(StringJoin["=&", Convert`TeX`ExpressionToTeX@#, "\\\\"]& /@ steps),
"\\end{aligned}"
}, "\n"]


(* ::Subsection::Closed:: *)
(*Output Display*)


replaceDistAndInt = # /. {Rubi`Dist -> Times, Rubi`Int -> Integrate} &;


$SubstitutionInformationSeperator = {",", " "};

SubstitutionInformation /: MakeBoxes[SubstitutionInformation[expr_, {}], form_] := MakeBoxes[expr, form]

SubstitutionInformation /: MakeBoxes[SubstitutionInformation[expr_, rules:{{_,_}..}], form_] := With[
{
info = RowBox@Riffle[MakeBoxes[#, form]&/@#, "\[LongEqual]"]&/@rules //Riffle[#, Unevaluated@Sequence[",", " "]]&
},
FormBox[
RowBox@{MakeBoxes[expr, form], Sequence@@$SubstitutionInformationSeperator, RowBox@info}
, form]
]


(* ::Subsection::Closed:: *)
(*Main Function*)


ShowIntSteps::nogenvar = ShowIntSteps::nogenvar::English =
"While turning off variable generation is needed, FormatType -> InputForm and \"SubstitutionInformation\" -> None is essential. Or mathematically wrong expressions will be returned.";


ShowIntSteps::nogenvar::ChineseSimplified =
"\:5982\:679c\:9700\:8981\:5173\:95ed\:53d8\:91cf\:751f\:6210\:ff0c\:5fc5\:987b\:5f00\:542f FormatType -> InputForm \:4ee5\:53ca \"SubstitutionInformation\" -> None \:3002\:5426\:5219\:5c06\:4f1a\:8fd4\:56de\:6570\:5b66\:4e0a\:9519\:8bef\:7684\:8868\:8fbe\:5f0f\:3002";


SetAttributes[ShowIntSteps, HoldFirst]

ShowIntSteps[expr_, var_Symbol, OptionsPattern[]] := Module[{
generatedUniqueSymbols = {}
}, With[{
symbolGenerationMethod = Switch[OptionValue/@{GeneratedParameters, FormatType, SubstitutionInformation},
{Identity|"Identity"|None|False, InputForm|"Original"|None|False, None|False},
Identity,
{Identity|"Identity"|None|False, __},
Message[ShowIntSteps::nogenvar];Identity, (* Force it not to be `Identity`, or let it be? *)
_,
OptionValue@GeneratedParameters
]
}, With[{
newVariableGenerator = Switch[symbolGenerationMethod,
Identity|"Identity"|None|False,
Identity,
Unique|"Unique",
(AppendTo[generatedUniqueSymbols, #];#)&@Unique[var] &,
_, (* Includes `Automatic|SingleLetter` *)
(AppendTo[generatedUniqueSymbols, #];#)&@Unique[tmp] &
]
}, Block[{Rubi`Private`$ShowSteps = True},
(* Evaluation *)
Reap[
FixedPoint[ (* Do not perform substitution until there's no other evaluation can be performed. *)
FixedPoint[
sowAndReturn@*Switch[OptionValue@SubstitutionInformation,
True|All, ForbidSubstitution[newVariableGenerator],
False|None, FromNewToOld@*ForbidSubstitution[newVariableGenerator],
_, ForbidSubstitution[newVariableGenerator]@*FromNewToOld (* Includes `Automatic` *)
],
#
] & /* PerformSubstitution,
Rubi`Int[expr, var]
]
, RubiStepTag] //CatenateReapWithSimplify[OptionValue@ComplexityFunction]
] // (* ReplaceGeneratedSymbol *) Function[{input},
With[{appearedSymbols = Append[var]@Cases[input, _Symbol, Infinity, Heads -> True]},
ReplaceGeneratedSymbol[input, Intersection[generatedUniqueSymbols, appearedSymbols], appearedSymbols, symbolGenerationMethod]
]
] // (* Convert to some form *) Switch[OptionValue@FormatType,
InputForm|"Original"|None|False,
DeleteDuplicates@ReplaceAll[#, NewSubstitution|OldSubstitution :> Rubi`Subst] &,
StandardForm|"Replaced"|Automatic|True,
replaceDistAndInt@*DeleteDuplicates@*ExtractSubstitutionInformation,
TraditionalForm|"Traditional"|"TraditionalForm",
TraditionalForm /@ DeleteDuplicates@ExtractSubstitutionInformation@# &,
TeXForm|"TeX"|"TeXForm",
RiffleTeXForm[HoldForm@Rubi`Int[expr, var]]@*DeleteDuplicates@*ExtractSubstitutionInformation
]
] ] ]

Options[ShowIntSteps] = {
ComplexityFunction -> StringLength@*ToString,
GeneratedParameters -> Automatic,
SubstitutionInformation -> Automatic,
FormatType -> StandardForm
};


(* ::Text:: *)
(*Provide option list.*)


ShowIntSteps["OptionList"] := {
FormatType -> InputForm|StandardForm|TraditionalForm|TeXForm,
GeneratedParameters -> Automatic|Unique|Identity|_,
SubstitutionInformation -> All|Automatic|None,
ComplexityFunction -> None|_
}


(* ::Section:: *)
(*TeXIntSteps*)


(* ::Text:: *)
(*An utility function is provided here due to frequent usage.*)


TeXIntSteps::MaTeXLoadFailMsg = RubiSteps`Loader`Message::RubiLoadFailMsg::English =
"Cannot load MaTeX`. RubiSteps`TeXIntSteps requires MaTeX`.";


TeXIntSteps::MaTeXLoadFailMsg::ChineseSimplified =
"\:65e0\:6cd5\:52a0\:8f7d MaTeX` \:3002RubiSteps`TeXIntSteps \:9700\:8981 MaTeX` \:3002";


TeXIntSteps[expr_, var_, opts___] := Enclose[
(
Confirm[Needs@"MaTeX`", TeXIntSteps::MaTeXLoadFailMsg];
Construct[Symbol["MaTeX`MaTeX"],
ShowIntSteps[
expr, var
, FormatType -> TeXForm]
, opts]
),
Message[RubiSteps`GeneralMessage`General::Failure, #]&
]


(* ::Chapter:: *)
(*End*)


End[]


EndPackage[]


(* ::Chapter:: *)
(*Modification*)


FormatValues@Rubi`Dist = {};
MakeBoxes[HoldPattern@Rubi`Dist[l_, int_Rubi`Int, _], form:TraditionalForm] ^:= RowBox@{MakeBoxes[l, form], MakeBoxes[int, form]};
MakeBoxes[HoldPattern@Rubi`Dist[l_, r_, _], form_] ^:= MakeBoxes[Times[l, r], form]


FormatValues@Rubi`Subst = {};
MakeBoxes[HoldPattern@Rubi`Subst[expr_, key_, val_], form:TraditionalForm] ^:= RowBox@{
UnderscriptBox["Subs",
RowBox@{
MakeBoxes[key, form], "\[RightArrow]", MakeBoxes[val, form]
}
],
RowBox@{
"(", MakeBoxes[expr, form], ")"
}
}
Loading

0 comments on commit 75741bf

Please sign in to comment.