Parameter Widgets#
Each parameter widget generates an HTML “chooser” in the page: a set of buttons, dropdowns, or other interactive elements with which the user can select a value.
The final value of a parameter widget, internally, is always an instance of some SymPy class. These values can be used by other parameter widgets, as inputs in computing their own sets of possible values, as well as by Display Widgets, in order to generate displays.
Format#
TYPE
:param
NAME
: Optional.LABEL
: Not accepted.ROLE_FIELD
: None.CONTENT_FIELD
: None.
Fields#
Required#
Field |
Type |
Description |
---|---|---|
|
enum |
A string saying which type of parameter it is. For the legal values, see Parameter types. |
|
string |
String to be used in TeX representations where the parameter is mentioned
(such as auto-generated Do not include dollar signs. For example, use |
Optional#
Field |
Type |
Description |
---|---|---|
|
any |
Some specification of an initial value for this parameter, i.e. the value it should have when first loaded in the page, and before the user has had a chance to interact with the chooser panel. The value you pass here may be of various JSON types; it is up to the specific parameter type to interpret. See Parameter types. If undefined, each parameter type has some default initial value. |
|
string |
Optional verbal description of the parameter, to be shown in the HTML display. Default: a standard description will be automatically generated. The standard description is usually to be preferred, and you should define your own only if the standard one is in some way insufficient or inaccurate. |
|
object |
A place to define any arguments, required and/or optional, for this parameter. Keys are argument names prescribed by the particular parameter type; values are any JSON type that in some way specifies a value (again, to be interpreted by the particular parameter type). See Parameter args. |
|
object |
Mapping from local names to relative libpaths of other parameters.
The local names may then occur within mathematical expressions
appearing as values in the |
Parameter args#
Most parameter types accept arguments, which may be required and/or optional.
These are passed in the args
field, in the form of an
object in which the keys are the argument names, and the values are whatever JSON types
are called for by the specific parameter type.
Example:
The Prime parameter, which represents a prime
number, accepts an optional odd
argument, where you can specify that it be an
odd prime.
.. pfsc-param::
:ptype: "Prime"
:args: {
odd: true
}
<param:>[]{
ptype: "Prime",
args: {
odd: true
}
}
Example:
The PrimRes parameter, which represents a primitive residue, requires
an argument m
for the modulus.
A PrimRes of modulus 7 can be defined like this:
.. pfsc-param::
:ptype: "PrimRes"
:args: {
m: 7
}
<param:>[]{
ptype: "PrimRes",
args: {
m: 7
}
}
Parameter imports#
Sometimes you may need to define the args
of one parameter in terms of the values of
one or more other parameters. You can do this using imports.
Imports are defined in a param
widget’s import
field, by passing an object
in which the keys are local names you choose for the imported parameters, and the
values are relative libpaths pointing to the widgets that define those parameters.
The local names you choose can then be used in expressions defining the args
.
Example:
Here we first define a param
widget representing a positive integer \(n\), and then
we define a second param
widget representing a divisor of \(n - 1\).
.. pfsc-param:: eg1_n:
:ptype: "Integer"
:init: 21
:args: {
gt: 0
}
.. pfsc-param:: eg1_d:
:ptype: "Divisor"
:init: 5
:import: {
n: eg1_n
}
:args: {
dividing: "n - 1"
}
<param:eg1_n>[]{
ptype: "Integer",
init: 21,
args: {
gt: 0
}
}
<param:eg1_d>[]{
ptype: "Divisor",
init: 5,
import: {
n: eg1_n
},
args: {
dividing: "n - 1"
}
}
Here, we can imagine that we are on a page where we plan to define several
“example explorers”, i.e. clusters of param
and disp
widgets designed
to illustrate an idea, and we’ve adopted a naming convention for our widgets
in which the first cluster gets names of the form eg1_VARNAME
, the next
cluster gets names of the form eg2_VARNAME
, and so on.
Thus, our first widget got the name eg1_n
. Our second widget was then able
to import the value of this one under the local name n
, by defining the
import
object,
{
n: eg1_n
}
in which the desired local name n
points to a relative libpath eg1_n
resolving to the desired param
widget.
Finally, the second widget, of Divisor type, was able to state that it was
a divisor of “one less than that integer”, by defining the args
object,
{
dividing: "n - 1"
}
Here, the value of the dividing
arg (the sole required arg for Divisor parameters)
was set equal to a string giving an algebraic expression in terms of the local names
defined in the import
object. See alg-expr.
Thus, with the first parameter’s initial value of 21, the second parameter is initially required to be a divisor of 20.
Arg-name shortcut#
There is a shortcut for importing a parameter, and setting its value directly as the value of an arg:
If you import a parameter under a local name equal to an arg name, and you do not explicitly define that arg, then the arg is automatically assigned the value of the parameter.
Example: In contrast to the last example we considered, suppose we want a positive integer \(n\), and a divisor not of \(n - 1\) but of \(n\) itself. Then we can use the arg-name shortcut like this:
.. pfsc-param:: eg2_n:
:ptype: "Integer"
:init: 20
:args: {
gt: 0
}
.. pfsc-param:: eg2_d:
:ptype: "Divisor"
:init: 5
:import: {
dividing: eg2_n
}
<param:eg2_n>[]{
ptype: "Integer",
init: 20,
args: {
gt: 0
}
}
<param:eg2_d>[]{
ptype: "Divisor",
init: 5,
import: {
dividing: eg2_n
}
}
Because we imported Integer parameter eg2_n
under the local name dividing
,
which is exactly equal to the one arg name required by the Divisor parameter,
we did not have to define the second parameter’s args
field at all.
The code above is thus a shortcut for the following clunkier (but no less correct) version:
.. pfsc-param:: eg2_n:
:ptype: "Integer"
:init: 20
:args: {
gt: 0
}
.. pfsc-param:: eg2_d:
:ptype: "Divisor"
:init: 5
:import: {
n: eg2_n
}
:args: {
dividing: "n"
}
<param:eg2_n>[]{
ptype: "Integer",
init: 20,
args: {
gt: 0
}
}
<param:eg2_d>[]{
ptype: "Divisor",
init: 5,
import: {
n: eg2_n
},
args: {
dividing: "n"
}
}
Special data types#
In addition to the usual types of Proofscape-flavored JSON, we need a few special, “compound” data types, in order to define the arguments accepted by the various parameter types.
alg-expr#
As explained in Parameter imports,
the reason for importing other parameters into a given one,
under the import
field, is to use them in expressions in the args
field.
In terms of JSON, these expressions are strings.
We take a moment now to define the precise form of these strings.
To recall a phrase introduced above, the keys in the import
object assign
local names to the imported parameters. The legal expressions that can then
be built are algebraic expressions in the local names.
When a string of this form is required in a parameter’s args
, we refer to
it as an alg-expr (read “algebraic expression”).
A value in the
args
object in aparam
widget is called an alg-expr if it is a string expressing a valid algebraic expression, built up using any or all of the local names introduced in the widget’simport
field, together with integers, parentheses, and the binary operation symbols+, -, *, /, ^, **
(where**
is a synonym for^
and means exponentiation).
Examples:
Supposing a param
widget in which the import
field imports other parameters under
the names a
, b
, c
, r
, s
, x
, y
, theta
, each of the following
lines defines a string that is a valid alg-expr:
"x"
"theta"
"2"
"x^3 + y - 7"
"(x - 2)*(4*y + 3)"
"x^-3"
"(2*a^3 + b*c - 7)/(-r + s^(1/2))"
int-valued#
By an int-valued, we will mean either a JSON int, or else an alg-expr
(thus, a JSON string) that
evaluates to a SymPy Integer
, given the current values of the parameters appearing
within it.
For example, 3
is a valid int-valued, while, if we have imported an Integer parameter
under local name n
, then "n + 2"
is another int-valued.
param-valued#
By a param-valued, we will mean an alg-expr string that simply names a single
parameter. For example, after importing a parameter under local name x
, then
"x"
would be a valid param-valued string.
Tip
Usually, when an arg calls for a param-valued input, it means you should be using the Arg-name shortcut instead.
Parameter types#
At present there is only a small set of available parameter types, but the list can be expected to grow in future versions of Proofscape.
Tip
See Editable sections, for passing input values to display widgets, for which there are not yet existing parameter types.
It is important to understand that, when you are choosing a parameter type, you are choosing more than the type of the final SymPy value; you are also choosing what kind of HTML interface you are going to generate in the page, to help the user select a value.
For example, each of the “Divisor”, “Prime”, and “Integer” parameter types produces a SymPy Integer
.
But the “Divisor” parameter is customized to help the user choose a divisor of another
integer, and the “Prime” parameter is customized to help the user choose a prime.
Divisor#
A rational integer dividing another.
SymPy value type:
Integer
ptype
:"Divisor"
init
:Type
Description
int
The value of the divisor.
Default:
1
, unless thesign
arg is defined and equal to-1
, in which case-1
.args
:Required:
arg name
Type
Description
dividing
int-valued
The number of which this is a divisor.
Optional:
arg name
Type
Description
sign
int
1
if you want only positive divisors-1
if you want only negative divisors0
if you allow both positive and negative divisors
Default:
1
Integer#
A rational integer.
SymPy value type:
Integer
ptype
:"Integer"
init
:Type
Description
int
The value of the integer.
Default:
0
.Note that this disregards any optional args you may have defined. If you define optional args, you should also pick an initial value that satisfies them.
args
:Required: None.
Optional:
Note
The optional args to the
Integer
parameter modify the displayed description, as well as error checking, but do not constrain the input interface. In other words, the user will be told what type of integer is called for, but can still enter an unacceptable value. In that case, an appropriate error message will be displayed.arg name
Type
Description
coprimeTo
int-valued
Must be coprime to this.
dividing
int-valued
Must divide this.
Note: For a chooser interface that helps the user select a divisor, use the Divisor parameter type instead.
gt
int-valued
Must be greater than this.
lt
int-valued
Must be less than this.
NumberField#
An algebraic number field.
SymPy value type:
AlgebraicField
ptype
:"NumberField"
init
:Type
Description
string
Pass a string giving any irreducible, univariate polynomial \(f\) over the integers, in order to construct a field obtained by adjoining to \(\mathbb{Q}\) a root of \(f\). (See
rootIndex
arg, below.)You can use any letter you want (
x
,y
,z
, etc.) as the variable of the polynomial.string
Pass
"cyc(n)"
or"cyclotomic_poly(n)"
as a shortcut to construct the nth cyclotomic field.Default:
"cyc(2)"
(i.e. the rationals \(\mathbb{Q}\))args
:Required: None.
Optional:
arg name
Type
Description
gen
string
Symbol name to use for a generator of the field. For example,
"theta"
. If supplied, it will be included in the description of the field, as in “\(\mathbb{Q}(\theta)\)”; otherwise, the field is described only as a quotient of a polynomial ring, as in “\(\mathbb{Q}[x]/(f(x))\)”.Default:
"zeta"
for"cyc(n)"
, else undefined.var
string
Symbol name to use for the variable in the field’s defining, irreducible polynomial.
Default:
"x"
for"cyc(n)"
, or the given variable for polynomials given explicitly.rootIndex
int
Index into the list of roots returned by SymPy’s
CRootOf
constructor, indicating which root of the minimal polynomial to use as primitive element for the field.The root ordering is as follows: Real roots come first, in increasing order, followed by complex roots, which are sorted first by real part (increasing) and then by imaginary part (increasing).
Default:
-1
, meaning the last root in the list. This selects the “canonical” root in the common cases of cyclotomic fields (the root of minimal complex argument), and quadratic fields defined by binomials \(x^2 - a\) (the root with positive real or imaginary part).
Prime#
A prime rational integer.
SymPy value type:
Integer
ptype
:"Prime"
init
:Type
Description
int
The value of the prime.
Default:
3
if theodd
arg is set, else2
.args
:Required: None.
Optional:
arg name
Type
Description
odd
boolean
Set
true
to require that it be an odd prime.Default:
false
chooserUpperBound
int
If positive, do not display primes larger than this in the chooser HTML.
Default:
0
(no upper bound)Note: This is not necessarily a mathematical constraint; you are not implying that the prime actually needs to be bounded for any mathematical reason. You are only saying that you want to limit the set of primes offered in the HTML chooser. So the reasons for the limit may be practical ones, relating to computation time, or surveyability of displays.
PrimeIdeal#
A prime ideal in the ring of integers of an algebraic number field.
SymPy value type:
PrimeIdeal
ptype
:"PrimeIdeal"
init
:Type
Description
int
Zero-based index into the list of PrimeIdeals computed by SymPy.
Default:
0
args
:Required:
arg name
Type
Description
k
Must point to a param widget of
NumberField
type. This is the field in whose ring of integers the prime ideal is to live.p
int-valued
The rational prime whose ideal divisors we are to represent.
Optional: None.
PrimRes#
A rational integer that is a primitive residue modulo another.
SymPy value type:
Integer
ptype
:"PrimRes"
init
:Type
Description
int
The value of the primitive residue.
Default: The value returned by the SymPy
primitive_root()
function, on the modulusm
specified underargs
.args
:Required:
arg name
Type
Description
m
int-valued
The modulus for which this is a primitive residue.
Optional: None.