# Is it possible to customize the Suggestions Bar?

I'd like to be able to customize the Suggestions Bar in v9.0 to provide recommendations of my own. Possible example: when doing unit calculations, I'd like it to suggest converting the answer to reduced SI units, or whatever class of units are appropriate.

My idea is to use the Suggestions Bar interface to lead a student along a path of self-discovery by leaving the right breadcrumbs at the right time.

I didn't see anything in the documentation... is this possible? Or should I implement some other interactive feature to get the same result: like an embedded palette?

-
Interesting idea (+1). Looking at the preferences, the only customization is to turn it off/on, so anything beyond that is unfortunately going to involve some hacking... –  Jens Dec 18 '12 at 19:08
I noticed that when you click on "Send Feedback", you can list what you'd like to see added/removed as suggestions to different output. Hopefully popular changes are updated via packlet data. I don't want to have to make all the recommendations and then purchase them in a later version. –  cjpembo Dec 18 '12 at 20:48
@cjpembo Yes, they're updated. It was mentioned in the experts live session. –  Szabolcs Dec 18 '12 at 21:36
@ Szabolcs Cool. How does Mathematica know when new packlet data is available? Can Wolfram "push" it? –  cjpembo Dec 18 '12 at 21:39
Messages to the user outside of the (possibly hidden) source code are also possible using Theodore Gray's (theodore@wolfram.com) "SetNotebookStatusLine" packet : "ShowStatus[status_] := LinkWrite[$ParentLink, SetNotebookStatusLine[FrontEndEvaluationNotebook[] , ToString[status]]]". It's mainly used for monitoring the status of long calculations, but could also serve your specifice ends. – Wouter Mar 26 '14 at 15:40 ## 1 Answer Yes! It is possible, although it takes some spelunking. Upon some searching with Names, I came across three relevant contexts where the predictive interface functions live: PredictiveInterface, PredictiveInterfaceDump, and Predictions. This last one is where the action happens. Luckily, the symbols were only ReadProtected, and their source code was readily available using Definition. The main function that generates the predictions is PredictionMakePredictions. Inside the function, a semantic type is generated based on the previous input and output cells, along with an attribute vector that holds some extra information about the expression, and then the relevant predictive actions are chosen based on that type. The type generation comes from the function PredictionsPrivateAttributeVectorAndSemanticTypes. The list of all the types with their corresponding action names exists in the form of a Dispatch table in PredictionsPrivatePredictionRuleNameRules. Entries in this list have the form type_ -> actionNames_List. For example, the "Quantity" type entry looks like this: "Quantity" -> {"QuantityMagnitude", "QuantityUnit", "NumericalValue", "QuantityDimensions", "UnitConvertToSystem", "UnitConvertToUnit", "UnitSimplify", "QuantityForm"}  where each of the strings in the list on the right-hand side is the name of an action. Once a type is chosen and its corresponding action names have been found, the action is called using PredictionsPredictionRule. PredictionsPredictionRule has many DownValues for all the relevant combinations of action name and attribute vector. The general form of the function is PredictionsPredictionRule[actionName_, attributeVector_List, PredictionsInOut[in_, out_]]  It looks like the generic attribute vector pattern is $genericAttributeVectorPattern = ConstantArray[_, 255];


PredictionsPredictionRule returns a PredictionsPrediction object, which has the form

PredictionsPrediction[
rank_,
categoryLabel_,
actionLabel_,
action_
]


where rank is some type of score, categoryLabel and actionLabel are strings for front-end displaying, and action is a function that takes in the previous cell's input and output. For example, the generic PredictionsPrediction for "QuantityMagnitude" is

PredictionsPrediction[
0.6,
PredictionsruleTextResource["categoryQuantities"],
PredictionsruleTextResource["actionMagnitude"],
HoldComplete[QuantityMagnitude[#2]] &
]


The text resource strings are stored in

$predictiveInterfaceRuleStringsPath = FileNameJoin[{$UserBaseDirectory, "Paclets", "Repository", "PredictiveInterface-Mac-2.3.0", "FrontEnd", "TextResources", "PredictiveRuleStrings.tr"}];


where you should replace "PredictiveInterface-Mac-2.3.0" with your corresponding OS and version.

So, to add a new predictive action (using an existing type):

1. Add your new action name to the Dispatch table in PredictionsPrivatePredictionRuleNameRules:

addPredictionRuleName[type_String, name_String] := Block[{oldNameRules, newNameRules},
oldNameRules = PredictionsPrivatePredictionRuleNameRules[];
newNameRules = oldNameRules[[1]] /. HoldPattern[type -> {names___}] :> (type -> DeleteDuplicates[{names, name}]);
PredictionsPrivatePredictionRuleNameRules[] = Dispatch[newNameRules];
]


For example, calling addPredictionRuleName["Quantity", "QuantityTimesTwo"] will add a new action name "QuantityTimesTwo" under the type "Quantity".

2. Add a new DownValue to PredictionsPredictionRule for your action name. For example:

PredictionsPredictionRule[
"QuantityTimesTwo",
\$genericAttributeVectorPattern,
PredictionsInOut[in_, out_]
] := PredictionsPrediction[
0.9,
"quantities",
"quantity times two",
HoldComplete[2*#2] &
]


That's it! I haven't played with adding new types to the system, but I'm sure that's possible too.

-
This must have taken a lot of work! +1 on the basis of effort alone. (I haven't tested it yet.) –  Mr.Wizard Jan 16 at 23:59
One application of this could be a button to upload the output to SE, something similar to this. –  Chip Hurst Jan 19 at 18:12
+1! PS. In paragraph 4 line 1, there seems be a typo: PredictionsMakePredictions . –  Silvia May 16 at 3:41