/* comment */ // comment |
a+b; // get result a + /* add them */ b; |
Prog(statement1, statement2, ...) [ statement1; statement2; ... ] |
Prog(a,b); is the same as typing [a;b;]; and is very useful for writing out function bodies. The [ ... ] construct is a syntactically nicer version of the Prog call; it is converted into Prog(...) during the parsing stage.
Bodied("op", precedence) Infix("op") Infix("op", precedence) Postfix("op") Postfix("op", precedence) Prefix("op") Prefix("op", precedence) |
precedence -- nonnegative integer (evaluated)
"Bodied" functions have all arguments except the first one inside parentheses and the last argument outside, for example:
For(pre, condition, post) statement; |
D(x) Sin(x)+Cos(x) |
"Infix" functions must have two arguments and are syntactically placed between their arguments. Names of infix functions can be arbitrary, although for reasons of readability they are usually made of non-alphabetic characters.
"Prefix" functions must have one argument and are syntactically placed before their argument. "Postfix" functions must have one argument and are syntactically placed after their argument.
Function name can be any string but meaningful usage and readability would require it to be either made up entirely of letters or entirely of non-letter characters (such as "+", ":" etc.). Precedence is optional (will be set to 0 by default).
In> YY x := x+1; CommandLine(1) : Error parsing expression In> Prefix("YY", 2) Out> True; In> YY x := x+1; Out> True; In> YY YY 2*3 Out> 12; In> Infix("##", 5) Out> True; In> a ## b ## c Out> a##b##c; |
Note that, due to a current parser limitation, a function atom that is declared prefix cannot be used by itself as an argument.
In> YY CommandLine(1) : Error parsing expression |
IsBodied("op") IsInfix("op") IsPostfix("op") IsPrefix("op") |
In> IsInfix("+"); Out> True; In> IsBodied("While"); Out> True; In> IsBodied("Sin"); Out> False; In> IsPostfix("!"); Out> True; |
OpPrecedence("op") OpLeftPrecedence("op") OpRightPrecedence("op") |
For infix operators, right precedence can differ from left precedence. Bodied functions and prefix operators cannot have left precedence, while postfix operators cannot have right precedence; for these operators, there is only one value of precedence.
In> OpPrecedence("+") Out> 6; In> OpLeftPrecedence("!") Out> 0; |
RightAssociative("op") |
RightAssociative("*") |
LeftPrecedence("op",precedence) RightPrecedence("op",precedence) |
precedence -- nonnegative integer
This functionality was required in order to display expressions like a-(b-c) correctly. Thus, a+b+c is the same as a+(b+c), but a-(b-c) is not the same as a-b-c.
Note that the left and right precedence of an infix operator does not affect the way Yacas interprets expressions typed by the user. You cannot make Yacas parse a-b-c as a-(b-c) unless you declare the operator "-" to be right-associative.
RuleBase(name,params) |
params -- list of arguments to function
In the context of the transformation rule declaration facilities this is a useful function in that it allows the stating of argument names that can he used with HoldArg.
Functions can be overloaded: the same function can be defined with different number of arguments.
RuleBaseListed("name", params) |
params -- list of arguments to function
A function defined using RuleBaseListed will appear to have the arity equal to the number of parameters in the param list, and it can accept any number of arguments greater or equal than that. As a consequence, it will be impossible to define a new function with the same name and with a greater arity.
The function body will know that the function is passed more arguments than the length of the param list, because the last argument will then be a list. The rest then works like a RuleBase-defined function with a fixed number of arguments. Transformation rules can be defined for the new function as usual.
RuleBaseListed("f",{a,b,c}) 10 # f(_a,_b,{_c,_d}) <-- Echo({"four args",a,b,c,d}); 20 # f(_a,_b,c_IsList) <-- Echo({"more than four args",a,b,c}); 30 # f(_a,_b,_c) <-- Echo({"three args",a,b,c}); |
In> f(A) Out> f(A); In> f(A,B) Out> f(A,B); In> f(A,B,C) three args A B C Out> True; In> f(A,B,C,D) four args A B C D Out> True; In> f(A,B,C,D,E) more than four args A B {C,D,E} Out> True; In> f(A,B,C,D,E,E) more than four args A B {C,D,E,E} Out> True; |
The function f now appears to occupy all arities greater than 3:
In> RuleBase("f", {x,y,z,t}); CommandLine(1) : Rule base with this arity already defined |
Rule("operator", arity, precedence, predicate) body |
arity, precedence -- integers
predicate -- function returning boolean
body -- expression, body of rule
The arity for a rules database equals the number of arguments. Different rules data bases can be built for functions with the same name but with a different number of arguments.
Rules with a low precedence value will be tried before rules with a high value, so a rule with precedence 0 will be tried before a rule with precedence 1.
HoldArg("operator",parameter) |
parameter -- atom, symbolic name of parameter
The parameter must be an atom from the list of symbolic arguments used when calling RuleBase.
Retract("function",arity) |
arity -- positive integer
Assignment := of a function does this to the function being (re)defined.
UnFence("operator",arity) |
arity -- positive integers
The standard library functions For and ForEach use UnFence.
HoldArgNr("function", arity, argNum) |
arity, argNum -- positive integers
RuleBaseArgList("operator", arity) |
arity -- integer
Make sure that the arguments of Macro... commands evaluate to expressions that would normally be used in the non-macro versions!
`(expression) |
To invoke this functionality, a backquote ` needs to be placed in front of an expression. Parentheses around the expression are needed because the backquote binds tighter than other operators.
The expression should contain some variables (assigned atoms) with the special prefix operator @. Variables prefixed by @ will be evaluated even if they are inside function arguments that are normally not evaluated (e.g. functions declared with HoldArg). If the @var pair is in place of a function name, e.g. "@f(x)", then at the first stage of evaluation the function name itself is replaced, not the return value of the function (see example); so at the second stage of evaluation, a new function may be called.
One way to view backquoting is to view it as a parametric expression generator. @var pairs get substituted with the value of the variable var even in contexts where nothing would be evaluated. This effect can be also achieved using UnList and Hold but the resulting code is much more difficult to read and maintain.
This operation is relatively slow since a new expression is built before it is evaluated, but nonetheless backquoting is a powerful mechanism that sometimes allows to greatly simplify code.
In> Decl(f1,f2) := \ In> `(@f1(x_IsNumber) <-- N(@f2(x))); Out> True; In> Decl(nSin,Sin) Out> True; In> Sin(1) Out> Sin(1); In> nSin(1) Out> 0.8414709848; |
This example assigns the expression func(value) to variable var. Normally the first argument of Set would be unevaluated.
In> SetF(var,func,value) := \ In> `(Set(@var,@func(@value))); Out> True; In> SetF(a,Sin,x) Out> True; In> a Out> Sin(x); |
DefMacroRuleBase(name,params) |
params -- list of arguments
With the usual functions, the evaluation model is that of the applicative-order model of substitution, meaning that first the arguments are evaluated, and then the function is applied to the result of evaluating these arguments. The function is entered, and the code inside the function can not access local variables outside of its own local variables.
With macros, the evaluation model is that of the normal-order model of substitution, meaning that all occurrences of variables in an expression are first substituted into the body of the macro, and only then is the resulting expression evaluated in its calling environment. This is important, because then in principle a macro body can access the local variables from the calling environment, whereas functions can not do that.
As an example, suppose there is a function square, which squares its argument, and a function add, which adds its arguments. Suppose the definitions of these functions are:
add(x,y) <-- x+y; |
square(x) <-- x*x; |
add(square(2),square(3)) |
add(4,9) |
In contrast, when add is a macro, the arguments to add are first expanded. So
add(square(2),square(3)) |
square(2) + square(3) |
Macros are useful for customizing syntax, and compilers can potentially greatly optimize macros, as they can be inlined in the calling environment, and optimized accordingly.
There are disadvantages, however. In interpreted mode, macros are slower, as the requirement for substitution means that a new expression to be evaluated has to be created on the fly. Also, when one of the parameters to the macro occur more than once in the body of the macro, it is evaluated multiple times.
When defining transformation rules for macros, the variables to be substituted need to be preceded by the @ operator, similar to the back-quoting mechanism. Apart from that, the two are similar, and all transformation rules can also be applied to macros.
Macros can co-exist with functions with the same name but different arity. For instance, one can have a function foo(a,b) with two arguments, and a macro foo(a,b,c) with three arguments.
In> DefMacroRuleBase("myfor",{init,pred,inc,body}) Out> True; In> myfor(_init,_pred,_inc,_body)<--[@init;While(@pred)[@body;@inc;];True;]; Out> True; In> a:=10 Out> 10; In> myfor(i:=1,i<10,i++,Echo(a*i)) 10 20 30 40 50 60 70 80 90 Out> True; In> i Out> 10; |
DefMacroRuleBaseListed("name", params) |
params -- list of arguments to function
SetExtraInfo(expr,tag) GetExtraInfo(expr) |
tag -- tag information (any other expression)
The function SetExtraInfo returns the tagged expression, leaving the original expression alone. This means there is a common pitfall: be sure to assign the returned value to a variable, or the tagged expression is lost when the temporary object is destroyed.
The original expression is left unmodified, and the tagged expression returned, in order to keep the atomic objects small. To tag an object, a new type of object is created from the old object, with one added property (the tag). The tag can be any expression whatsoever.
The function GetExtraInfo(x) retrieves this tag expression from an object x. If an object has no tag, it looks the same as if it had a tag with value False.
No part of the Yacas core uses tags in a way that is visible to the outside world, so for specific purposes a programmer can devise a format to use for tag information. Association lists (hashes) are a natural fit for this, although it is not required and a tag can be any object (except the atom False because it is indistinguishable from having no tag information). Using association lists is highly advised since it is most likely to be the format used by other parts of the library, and one needs to avoid clashes with other library code. Typically, an object will either have no tag or a tag which is an associative list (perhaps empty). A script that uses tagged objects will check whether an object has a tag and if so, will add or modify certain entries of the association list, preserving any other tag information.
Note that FlatCopy currently does not copy the tag information (see examples).
In> a:=2*b Out> 2*b; In> a:=SetExtraInfo(a,{{"type","integer"}}) Out> 2*b; In> a Out> 2*b; In> GetExtraInfo(a) Out> {{"type","integer"}}; In> GetExtraInfo(a)["type"] Out> "integer"; In> c:=a Out> 2*b; In> GetExtraInfo(c) Out> {{"type","integer"}}; In> c Out> 2*b; In> d:=FlatCopy(a); Out> 2*b; In> GetExtraInfo(d) Out> False; |
GarbageCollect() |
Reference counting refers to bookkeeping where in each object a counter is held, keeping track of the number of parts in the system using that object. When this count drops to zero, the object is automatically removed. Reference counting is not the fastest way of doing garbage collection, but it can be implemented in a very clean way with very little code.
Among the most important objects that are not reference counted are the strings. GarbageCollect collects these and disposes of them when they are not used any more.
GarbageCollect is useful when doing a lot of text processing, to clean up the text buffers. It is not highly needed, but it keeps memory use low.
FindFunction(function) |
In> FindFunction("Sum") Out> "sums.rep/code.ys"; In> FindFunction("Integrate") Out> "integrate.rep/code.ys"; |
Secure(body) |
MultiplyNum(x,y) MultiplyNum(x,y,z,...) MultiplyNum({x,y,z,...}) |
The function accepts any number of arguments (not less than two) or a list of numbers. The result is always a floating-point number (even if Numeric is not set).
CachedConstant(cache, Cname, Cfunc) |
Cname -- atom, name of the constant
Cfunc -- expression that evaluates the constant
The call to CachedConstant defines a new function named Cname() that returns the value of the constant at given precision. If the precision is increased, the value will be recalculated as necessary, otherwise calling Cname() will take very little time.
The parameter Cfunc must be an expression that can be evaluated and returns the value of the desired constant at the current precision. (Most arbitrary-precision mathematical functions do this by default.)
The associative list cache contains elements of the form {Cname, prec, value}, as illustrated in the example. If this list does not exist, it will be created.
This mechanism is currently used by N() to precompute the values of Pi and gamma. The name of the cache for N() is CacheOfConstantsN. The code in the function N() assigns unevaluated calls to Pi() and gamma() to the atoms Pi and gamma and declares them LazyGlobal. The result is that the constants will be recalculated only when they are used in the expression under N(). In other words, the code in N() does the equivalent of
Pi := Hold(Pi()); gamma := Hold(gamma()); LazyGlobal(Pi); LazyGlobal(gamma); |
In> CachedConstant( my'cache, Ln2, LnNum(2) ) Out> 0.6931471806; In> Ln2 Out> Ln2; In> Ln2() Out> 0.6931471806; In> [ Precision(20); V( Ln2() ); ] CachedConstant: Info: constant Ln2 is being recalculated at precision 20 Out> 0.69314718055994530942; In> my'cache Out> {{"Ln2",20,0.69314718055994530942}}; |
NewtonNum(func, x0, prec0, order) NewtonNum(func, x0, prec0) NewtonNum(func, x0) |
x0 -- initial value (must be close enough to the root)
prec0 -- initial precision (at least 4, default 5)
order -- convergence order (typically 2 or 3, default 2)
NewtonNum will iterate the given function starting from the initial value, until the sequence converges within current precision. Initially, up to 5 iterations at the initial precision prec0 is performed (the low precision is set for speed). The initial value x0 must be close enough to the root so that the initial iterations converge. If the sequence does not produce even a single correct digit of the root after these initial iterations, an error message is printed. The default value of the initial precision is 5.
The order parameter should give the convergence order of the scheme. Normally, Newton iteration converges quadratically (so the default value is order=2) but some schemes converge faster and you can speed up this function by specifying the correct order. (Caution: if you give order=3 but the sequence is actually quadratic, the result will be silently incorrect. It is safe to use order=2.)
In> Precision(20) Out> True; In> NewtonNum({{x}, x+Sin(x)}, 3, 5, 3) Out> 3.14159265358979323846; |
SumTaylorNum(x, NthTerm, order) SumTaylorNum(x, NthTerm, TermFactor, order) SumTaylorNum(x, ZerothTerm, TermFactor, order) |
ZerothTerm -- value of the 0-th coefficient of the series
x -- number, value of the expansion variable
TermFactor -- a function specifying the ratio of n-th term to the previous one
order -- power of x in the last term
The coefficients a[k] of the Taylor series are given as functions of one integer variable (k). It is convenient to pass them to SumTaylorNum as closures. For example, if a function a(k) is defined, then
SumTaylorNum(x, {{k}, a(k)}, n) |
Often a simple relation between successive coefficients a[k-1], a[k] of the series is available; usually they are related by a rational factor. In this case, the second form of SumTaylorNum should be used because it will compute the series faster. The function TermFactor applied to an integer k>=1 must return the ratio a[k]/a[k-1]. (If possible, the function TermFactor should return a rational number and not a floating-point number.) The function NthTerm may also be given, but the current implementation only calls NthTerm(0) and obtains all other coefficients by using TermFactor. Instead of the function NthTerm, a number giving the 0-th term can be given.
The algorithm is described elsewhere in the documentation. The number of terms order+1 must be specified and a sufficiently high precision must be preset in advance to achieve the desired accuracy. (The function SumTaylorNum does not change the current precision.)
In> Precision(21) Out> True; In> SumTaylorNum(1, {{k},1/k!}, 21) Out> 2.718281828459045235351; In> SumTaylorNum(1, 1, {{k},1/k}, 21) Out> 2.71828182845904523535; In> SumTaylorNum(1, {{k},1/k!}, {{k},1/k}, 21) Out> 2.71828182845904523535; In> RoundTo(N(Ln(%)),20) Out> 1; |
IntPowerNum(x, n, mult, unity) |
n -- a non-negative integer (power to raise x to)
mult -- a function that performs one multiplication
unity -- value of the unity with respect to that multiplication
Mathematically, this function is a generalization of MathPower to rings other than that of real numbers.
In the current implementation, the unity argument is only used when the given power n is zero.
In> IntPowerNum(3, 3, MathMultiply,1) Out> 27; |
In> IntPowerNum(3+4*I, 3, *,1) Out> Complex(-117,44); In> IntPowerNum(HilbertMatrix(2), 4, *, Identity(2)) Out> {{289/144,29/27},{29/27,745/1296}}; |
In> IntPowerNum(3,100,{{x,y},Mod(x*y,7)},1) Out> 4; |
BinSplitNum(n1, n2, a, b, c, d) BinSplitData(n1,n2, a, b, c, d) BinSplitFinal({P,Q,B,T}) |
a, b, c, d -- functions of one argument, coefficients of the series
P, Q, B, T -- numbers, intermediate data as returned by BinSplitData
The last four arguments of BinSplitNum are functions of one argument that give the coefficients a(k), b(k), p(k), q(k). In most cases these will be short integers that are simple to determine. The binary splitting method will work also for non-integer coefficients, but the calculation will take much longer in that case.
Note: the binary splitting method outperforms the straightforward summation only if the multiplication of integers is faster than quadratic in the number of digits. See the algorithm documentation for more information.
The two other functions are low-level functions that allow a finer control over the calculation. The use of the low-level routines allows checkpointing or parallelization of a binary splitting calculation.
The binary splitting method recursively reduces the calculation of S(n[1],n[2]) to the same calculation for the two halves of the interval [n[1], n[2]]. The intermediate results of a binary splitting calculation are returned by BinSplitData and consist of four integers P, Q, B, T. These four integers are converted into the final answer S by the routine BinSplitFinal using the relation
In> Precision(21) Out> True; In> BinSplitNum(1,21, {{k},1}, {{k},1},{{k},1},{{k},k}) Out> 1.718281828459045235359; In> N(Exp(1)-1) Out> 1.71828182845904523536; In> BinSplitData(1,21, {{k},1}, {{k},1},{{k},1},{{k},k}) Out> {1,51090942171709440000,1, 87788637532500240022}; In> BinSplitFinal(%) Out> 1.718281828459045235359; |
MathGetExactBits(x) MathSetExactBits(x,bits) |
bits -- integer, number of bits
MathGetExactBits(x) returns an integer number n such that x represents a real number in the interval [ x*(1-2^(-n)), x*(1+2^(-n))] if x!=0 and in the interval [-2^(-n), 2^(-n)] if x=0. The integer n is always nonnegative unless x is zero (a "floating zero"). A floating zero can have a negative value of the number n of exact bits.
These functions are only meaningful for floating-point numbers. (All integers are always exact.) For integer x, the function MathGetExactBits returns the bit count of x and the function MathSetExactBits returns the unmodified integer x.
In> MathGetExactBits(1000.123) Out> 33; In> x:=MathSetExactBits(10., 20) Out> 10.; In> MathGetExactBits(x) Out> 20; |
In> x:=MathSetExactBits(0., -2) Out> 0.; In> x=0 Out> True; |
Check(predicate,"error text") TrapError(expression,errorHandler) GetCoreError() |
"error text" -- string to print on error
expression -- expression to evaluate (causing potential error)
errorHandler -- expression to be called to handle error
A "soft" error reporting facility that does not stop the execution is provided by the function Assert.
In> [Check(1=0,"bad value"); Echo(OK);] In function "Check" : CommandLine(1) : "bad value" |
Note that OK is not printed.
TrapError evaluates its argument expression, returning the result of evaluating expression. If an error occurs, errorHandler is evaluated, returning its return value in stead.
GetCoreError returns a string describing the core error. TrapError and GetCoreError can be used in combination to write a custom error handler.
Assert("str", expr) pred Assert("str") pred Assert() pred |
"str" -- string to classify the error
expr -- expression, error object
Unlike the "hard" error function Check, the function Assert does not stop the execution of the program.
The error object consists of the string "str" and an arbitrary expression expr. The string should be used to classify the kind of error that has occurred, for example "domain" or "format". The error object can be any expression that might be useful for handling the error later; for example, a list of erroneous values and explanations. The association list of error objects is currently the global variable ErrorTableau.
If the parameter expr is missing, Assert substitutes True. If both optional parameters "str" and expr are missing, Assert creates an error of class "generic".
Errors can be handled by a custom error handler in the portion of the code that is able to handle a certain class of errors. The functions IsError, GetError and ClearError can be used.
Normally, all errors posted to the error tableau during evaluation of an expression should be eventually printed to the screen. This is the behavior of prettyprinters DefaultPrint, Print, PrettyForm and TeXForm (but not of the inline prettyprinter, which is enabled by default); they call DumpErrors after evaluating the expression.
In> Assert("bad value", "must be zero") 1=0 Out> False; In> Assert("bad value", "must be one") 1=1 Out> True; In> IsError() Out> True; In> IsError("bad value") Out> True; In> IsError("bad file") Out> False; In> GetError("bad value"); Out> "must be zero"; In> DumpErrors() Error: bad value: must be zero Out> True; |
In> IsError() Out> False; In> DumpErrors() Out> True; |
DumpErrors() ClearErrors() |
ClearErrors is a trivial error handler that does nothing except it clears the tableau.
IsError() IsError("str") |
GetError("str") ClearError("str") |
GetError returns the error object if a custom error of class "str" has been reported using Assert, or False if no errors of this class have been reported.
ClearError("str") deletes the same error object that is returned by GetError("str"). It deletes at most one error object. It returns True if an object was found and deleted, and False otherwise.
In> x:=1 Out> 1; In> Assert("bad value", {x,"must be zero"}) x=0 Out> False; In> GetError("bad value") Out> {1, "must be zero"}; In> ClearError("bad value"); Out> True; In> IsError() Out> False; |
CurrentFile() CurrentLine() |
These functions are most useful in batch file calculations, where there is a need to determine at which line an error occurred. One can define a function
tst() := Echo({CurrentFile(),CurrentLine()}); |
It is important for a developer to know which functions are built-in and cannot be redefined or Retract-ed. Also, core functions may be somewhat faster to execute than functions defined in the script library. All core functions are listed in the file corefunctions.h in the src/ subdirectory of the Yacas source tree. The declarations typically look like this:
SetCommand(LispSubtract, "MathSubtract"); |
MathNot(expression) |
MathAnd(...) |
MathOr(...) |
MathOr is the basic logical "or" function. Similarly to And, it is lazy-evaluated. And(...) and Or(...) do also exist, defined in the script library. You can redefine them as infix operators yourself, so you have the choice of precedence. In the standard scripts they are in fact declared as infix operators, so you can write expr1 And expr.
BitAnd(n,m) BitOr(n,m) BitXor(n,m) |
Equals(a,b) |
GreaterThan(a,b) LessThan(a,b) |
In> LessThan(1,1) Out> False; In> LessThan("a","b") Out> True; |
MathGcd(n,m) (Greatest Common Divisor) MathAdd(x,y) (add two numbers) MathSubtract(x,y) (subtract two numbers) MathMultiply(x,y) (multiply two numbers) MathDivide(x,y) (divide two numbers) MathSqrt(x) (square root, must be x>=0) MathFloor(x) (largest integer not larger than x) MathCeil(x) (smallest integer not smaller than x) MathAbs(x) (absolute value of x, or |x| ) MathExp(x) (exponential, base 2.718...) MathLog(x) (natural logarithm, for x>0) MathPower(x,y) (power, x ^ y) MathSin(x) (sine) MathCos(x) (cosine) MathTan(x) (tangent) MathSinh(x) (hyperbolic sine) MathCosh(x) (hyperbolic cosine) MathTanh(x) (hyperbolic tangent) MathArcSin(x) (inverse sine) MathArcCos(x) (inverse cosine) MathArcTan(x) (inverse tangent) MathArcSinh(x) (inverse hyperbolic sine) MathArcCosh(x) (inverse hyperbolic cosine) MathArcTanh(x) (inverse hyperbolic tangent) MathDiv(x,y) (integer division, result is an integer) MathMod(x,y) (remainder of division, or x mod y) |
Note that all functions, such as the MathPower, MathSqrt, MathAdd etc., accept integers as well as floating-point numbers. The resulting values may be integers or floats. If the mathematical result is an exact integer, then the integer is returned. For example, MathSqrt(25) returns the integer 5, and MathPower(2,3) returns the integer 8. In such cases, the integer result is returned even if the calculation requires more digits than set by Precision. However, when the result is mathematically not an integer, the functions return a floating-point result which is correct only to the current precision.
In> Precision(10) Out> True In> Sqrt(10) Out> Sqrt(10) In> MathSqrt(10) Out> 3.16227766 In> MathSqrt(490000*2^150) Out> 26445252304070013196697600 In> MathSqrt(490000*2^150+1) Out> 0.264452523e26 In> MathPower(2,3) Out> 8 In> MathPower(2,-3) Out> 0.125 |
FastExp(x), FastLog(x) (natural logarithm), FastPower(x,y), FastSin(x), FastCos(x), FastTan(x), FastArcSin(x), FastArcCos(x), FastArcTan(x)
ShiftLeft(expr,bits) ShiftRight(expr,bits) |
IsPromptShown() |
MathLibrary() |
Possible names supported at the moment are "Internal" and "Gmp", indicating the internal math library libyacasnumbers and the GNU Multiple Precision library libgmp.
In> MathLibrary() Out> "Internal"; |
GetTime(expr) |
The result is the "user time" as reported by the OS, not the real ("wall clock") time. Therefore, any CPU-intensive processes running alongside Yacas will not significantly affect the result of GetTime.
In> GetTime(Simplify((a*b)/(b*a))) Out> 0.09; |
The plugin feature allows Yacas to interface with other libraries that support additional functionality. For example, there could be a plugin enabling the user to script a user interface from within Yacas, or a specific powerful library to do numeric calculations.
The plugin feature is currently in an experimental stage, and it will not work on each platform. To be precise, the libltdl library is used to load the plugins. This will only work on platforms which are supported by libltdl, which includes Linux, Mac OS X, Solaris, and HP-UX.
The remainder of the section is only of interest to users who want to write plugins themselves. It is assumed that the reader is comfortable programming in C++.
In addition to the plugin structure in the Yacas engine, there is a module cstubgen (currently still under development) that allows a rapid creation of a plugin that interfaces to an external library. Essentially all that is required is to write a file that looks like the header file of the original library, but written in Yacas syntax. The module cstubgen is then able to write out a C++ file that can be compiled and linked with the original library, and then loaded from within Yacas. To include a function in the plugin typically takes one line of Yacas code. There are a few examples in the plugins/ directory (the files ending with api.stub). The build system converts these automatically to the required C++ files.
In addition to the C++ stub file, cstubgen also automatically generates some documentation on the functions included in the stub. This documentation is put in a file with extension '.man.txt'.
An example describing the use of cstubgen can be found in the essay "Creating plugins for Yacas" . See Essays on Yacas, Chapter 5 for a description of the integration of plugins in the build system.
DllLoad(file) |
If the argument file does not specify a directory, all directories in the path for Yacas plugins are searched. This path is built up by calls to DllDirectory. In addition, it contains the default plugin directory which is specified by the command line option --dlldir (see The Yacas User's Function Reference, Chapter 1 ). If this option is not present, the default plugin directory is as specified at compile time (the default value is /usr/local/lib/yacas).
If the argument file does not specify the extension, then first the extension .la is appended. This is the standard extension for Libtool libraries. If no plugin with this name can be found, a platform-specific extension is tried (as an example, this is .so on platforms with ELF libraries).
In> DllLoad("example"); Out> True In> AddTwoIntegers(2,3); Out> 5 |
Note that it suffices to specify the string example. Yacas knows that the plugin resides in the file /usr/local/lib/yacas/example.la (if plugins are installed in the default locations).
DllUnload(file) |
DllUnload always returns True, even if no plugin with the name file is found.
In> DllLoad("example"); Out> True In> AddTwoIntegers(2,3); Out> 5 |
Then, we unload the plugin, and we check that the function AddTwoIntegers is indeed no longer defined.
In> DllUnload("example"); Out> True In> AddTwoIntegers(2,3); Out> AddTwoIntegers(2,3) |
DllEnumerate() |
In> DllEnumerate(); Out> {} |
This changes after we load the example plugin.
In> DllLoad("example"); Out> True In> DllEnumerate(); Out> {"example"} |
StubApiCStart(name) |
StubApiCPrettyName(name) |
This name is used for producing documentation. It will appear in the title of the documentation section describing the plugin.
StubApiCPrettyName("multithreaded GUI") |
StubApiCPluginPurpose(text) |
StubApiCShortIntegerConstant(const,value) |
value -- integer value the global should be bound to
#define FOO 10 |
StubApiCShortIntegerConstant("FOO","FOO") |
StubApiCInclude(file) |
StubApiCInclude("\<GL/gl.h\>") |
StubApiCInclude("\"GL/gl.h\"") |
StubApiCFunction(returntype,fname,args) StubApiCFunction(returntype,fname, fname2,args) |
fname -- function of built-in function
fname2 -- (optional) function name to be used from within Yacas
args -- list of arguments to the function
Return type, function name, and list of arguments should be literal strings (surrounded by quotes).
If fname2 is not supplied, it will be assumed to be the same as fname.
The return types currently supported are "int", "double" and "void".
The argument values that are currently supported are "int", "double", and "input_string".
Argument types can be specified simply as a string referring to their type, like "int", or they can be lists with an additional element stating the name of the variable: {"int","n"}. The variable will then show up in the automatically generated documentation as having the name "n".
StubApiCFunction("void","glVertex3d", {"double","double","double"}); |
StubApiCRemark(string) |
StubApiCSetEnv(func) |
There needs to ba a function in the plugin somewhere of the form
static LispEnvironment* env = NULL; void GlutSetEnv(LispEnvironment& aEnv) { env = &aEnv; } |
StubApiCSetEnv("GlutSetEnv"); |
StubApiCFile(pluginname,basename) |
basename -- name for the generation of the stub file
pluginname should be the name as passed to DllLoad. If the plugin name is loaded with DllLoad("example"), then pluginname should be "example".
StubApiCStruct(name) StubApiCStruct(name,freefunction) |
freefunction -- function that can be called to clean up the object
By default the struct will be deleted from memory with a normal call to free(...). This can be overridden with a function given as second argument, freefunction. This is needed in the case where there are additional operations that need to be performed in order to delete the object from memory.
typedef struct SomeStruct { int a; int b; } SomeStruct; |
StubApiCStruct("SomeStruct*") |
IsGeneric(object) |
GenericTypeName(object) |
EG
In> GenericTypeName(ArrayCreate(10,1)) Out> "Array"; |
ArrayCreate(size,init) |
ArraySize(array) |
ArrayGet(array,index) |
Arrays can also be accessed through the [] operators. So array[index] would return the same as ArrayGet(array, index).
ArraySet(array,index,element) |
Arrays can also be accessed through the [] operators. So array[index] := element would do the same as ArraySet(array, index,element).
ArrayCreateFromList(list) |
ListFromArray(array) |
Yacas comes with a test suite which can be found in the directory tests/. Typing
make test |
The verification commands described in this chapter only display the expressions that do not evaluate correctly. Errors do not terminate the execution of the Yacas script that uses these testing commands, since they are meant to be used in test scripts.
Verify(question,answer) TestYacas(question,answer) LogicVerify(question,answer) |
answer -- expected result after evaluation
For some calculations, the demand that two expressions are identical syntactically is too stringent. The Yacas system might change at various places in the future, but 1+x would still be equivalent, from a mathematical point of view, to x+1.
The general problem of deciding that two expressions a and b are equivalent, which is the same as saying that a-b=0 , is generally hard to decide on. The following commands solve this problem by having domain-specific comparisons.
The comparison commands do the following comparison types:
In> Verify(1+2,3) Out> True; In> Verify(x*(1+x),x^2+x) ****************** x*(x+1) evaluates to x*(x+1) which differs from x^2+x ****************** Out> False; In> TestYacas(x*(1+x),x^2+x) Out> True; In> Verify(a And c Or b And Not c,a Or b) ****************** a And c Or b And Not c evaluates to a And c Or b And Not c which differs from a Or b ****************** Out> False; In> LogicVerify(a And c Or b And Not c,a Or b) Out> True; In> LogicVerify(a And c Or b And Not c,b Or a) Out> True; |
KnownFailure(test) |
This might be used by developers when they have no time to fix the defect, but do not wish to alarm users who download Yacas and type make test.
In> KnownFailure(Verify(1,2)) Known failure: ****************** 1 evaluates to 1 which differs from 2 ****************** Out> False; In> KnownFailure(Verify(1,1)) Known failure: Failure resolved! Out> True; |
RoundTo(number,precision) |
precision -- precision to use for round-off
In> N(RoundTo(Exp(1),30),30) Out> 2.71828182110230114951959786552; In> N(RoundTo(Exp(1),20),20) Out> 2.71828182796964237096; |
VerifyArithmetic(x,n,m) RandVerifyArithmetic(n) VerifyDiv(u,v) |
VerifyArithmetic verifies for an arbitrary set of numbers x, n and m that
The left and right side represent two ways to arrive at the same result, and so an arithmetic module actually doing the calculation does the calculation in two different ways. The results should be exactly equal.
RandVerifyArithmetic(n) calls VerifyArithmetic with random values, n times.
VerifyDiv(u,v) checks that
In> VerifyArithmetic(100,50,60) Out> True; In> RandVerifyArithmetic(4) Out> True; In> VerifyDiv(x^2+2*x+3,x+1) Out> True; In> VerifyDiv(3,2) Out> True; |
Yacas allows to define functions with the same name but different arities, and different rules corresponding to these arities will be used. Also, it is possible to define a function with optional arguments, for example, Plot2D is one such function. Such functions can have any arity larger or equal to a certain minimum arity (the number of non-optional arguments).
Arrays are faster than lists but the array size cannot be changed.
Atoms can be of type string, number, or symbol. For example, y1 is a symbolic atom, 954 is a number atom, and "" is an (empty) string atom. Symbolic atoms are normally used in Yacas to denote mathematical unknowns and function names. Number and string atoms are used to denote values.
A symbolic atom can be bound to a value (in which case it becomes a variable), or to a rule or several rules (in which case it becomes a function). An atom can also have a property object.
Some constants take a long time to compute and therefore they are cached at the highest precision computed so far. These are the "cached constants".
In> Solve(Sin(x)==1, x) Out> {x==Pi/2}; |
The symbolic equation operator == is also useful to represent solutions of equations or to specify substitutions, give options, and so on.
Functions can be evaluated, that is, the rules bound to them may be executed. For example, Cos(Pi+0) is an expression that contains two functions and four atoms. The atom Pi is a symbolic atom which is normally not bound to anything. The atom 0 is a numeric atom.
The atoms Cos and + are symbolic atoms which are bound to appropriate simplification rules. So these two atoms are functions. Note that these functions have different syntax. Cos is a normal function which takes its arguments in parentheses. The atom + is a function with special syntax because "+" is placed between its arguments and no parentheses are used.
The rules to which + is bound are such that the expression Pi+0 is evaluated to the symbolic atom Pi. The rules for Cos are such that the expression Cos(Pi) is evaluated to the numeric atom -1. The example Yacas session is:
In> Cos(Pi+0) Out> -1; |
Some functions are built-in and implemented in C++, while others are library functions.
The built-in functions are usually less flexible than the library functions because they cannot be left unevaluated. Given incorrect arguments, a built-in function will generate an error. However, a user-defined function may simply return unevaluated in such cases.
Lists are ubiquitous in Yacas. Most data structures in the standard library is based on lists.
Lists are also used internally to represent Yacas expressions. For example, the expression Cos(x+1) is represented internally as a nested list:
In> FullForm( Cos(x+1) ) (Cos (+ x 1 )) Out> Cos(x+1); |
Some basic linear algebra operations on matrices are supported.
Apart from the syntax, operators are exactly the same as any other functions, they can have rules bound to them in the same way.
For example, the operator "+" binds less tightly (i.e. has a higher precedence value) than the operator "*" and so the expression a+b*c is parsed as a+(b*c), as one would expect.
Infix operators can have different left-side and right-side precedence. For example, the infix operator "-" has left precedence 70 and right precedence 40 -- this allows us to parse expressions such as a-b+c correctly, as a-b+c, and not as a-(b+c).
In> a:= SetExtraInfo(1+x,y); Out> 1+x; |
In> func1(x+0) Out> func1(x); |
Only expressions containing functions can be evaluated by rules. (Atoms are evaluated only if they are bound to a value.)
Several rules can be defined for a given function. Rules can be erased or added at run time.
In> D(x) Sin(x)+1 Out> Cos(x); |
Functions with special syntax can have different precedence.
In> a := 1 Out> 1; |
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
59 Temple Place, Suite 330 Boston, MA, 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.
The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.
A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not ``Transparent'' is called ``Opaque''.
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.
The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
You may add a section entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties -- for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections entitled ``History'' in the various original documents, forming one section entitled ``History''; likewise combine any sections entitled ``Acknowledgements'', and any sections entitled ``Dedications''. You must delete all sections entitled ``Endorsements.''
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
Copyright (C) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled ``GNU Free Documentation License''. |
If you have no Invariant Sections, write ``with no Invariant Sections'' instead of saying which ones are invariant. If you have no Front-Cover Texts, write ``no Front-Cover Texts'' instead of ``Front-Cover Texts being LIST''; likewise for Back-Cover Texts.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.