A context in Giac is an evaluation environment that encapsulates all the state needed to evaluate mathematical expressions. It provides isolation for variables, settings, and history while enabling controlled access to parent contexts.From global.h:
class context {public: sym_tab * tabptr; // Symbol table (variable bindings) context * globalcontextptr; // Current global context context * previous; // Parent context global * globalptr; // Global settings const context * parent; // Read-only parent vecteur * quoted_global_vars; // Global variables to quote vecteur * rootofs; // Algebraic extensions vecteur * history_in_ptr; // Input history vecteur * history_out_ptr; // Output history vecteur * history_plot_ptr; // Graphics history};
Each context has its own symbol table, preventing naming conflicts:
context ctx1, ctx2;// Set x=5 in ctx1gen x1("x", &ctx1);sto(gen(5), x1, &ctx1);// Set x=10 in ctx2 gen x2("x", &ctx2);sto(gen(10), x2, &ctx2);// x has different values in each contexteval(x1, 1, &ctx1); // Returns 5eval(x2, 1, &ctx2); // Returns 10
Configuration Management
Different contexts can have different settings:
context ctx1, ctx2;// Degrees in ctx1angle_mode(1, &ctx1); gen sin_45_deg = eval(gen("sin(45)", &ctx1), 1, &ctx1);// Radians in ctx2angle_mode(0, &ctx2);gen sin_45_rad = eval(gen("sin(45)", &ctx2), 1, &ctx2);
Thread Safety
Each thread can have its own context for safe parallel computation:
void worker_thread(const gen & expr) { context thread_ctx; // Local context for this thread gen result = eval(expr, 1, &thread_ctx); // No interference with other threads}
Session Management
Contexts store evaluation history and can be saved/restored:
context session;// ... user interaction ...// Save sessiongen state = giac_current_status(true, &session);// Later: restore session unarchive_session(state, 1, undef, &session);
// Get angle modeint mode = angle_mode(contextptr);// Set to degrees angle_mode(1, contextptr);// Check if in complex modeif (complex_mode(contextptr)) { // Complex arithmetic enabled}// Set numerical toleranceepsilon(1e-10, contextptr);
// Function that requires a contextgen my_function(const gen & arg, GIAC_CONTEXT) { // contextptr is available here return eval(arg, 1, contextptr);}// Function with optional context (defaults to context0)gen another_function(const gen & arg, GIAC_CONTEXT0) { if (!contextptr) contextptr = context0; return eval(arg, 1, contextptr);}
gen evaluate_in_degrees(const gen & expr, GIAC_CONTEXT) { // Save current mode int old_mode = angle_mode(contextptr); // Temporarily switch to degrees angle_mode(1, contextptr); // Evaluate gen result = eval(expr, 1, contextptr); // Restore mode angle_mode(old_mode, contextptr); return result;}
gen function_with_locals(const gen & arg, GIAC_CONTEXT) { context local_ctx; local_ctx.previous = const_cast<context*>(contextptr); local_ctx.globalcontextptr = const_cast<context*>(contextptr); // Create local variable gen x("x", &local_ctx); sto(arg, x, &local_ctx); // Evaluate with local x gen body = gen("x^2 + 1", &local_ctx); gen result = eval(body, 1, &local_ctx); // local_ctx destroyed here, x goes out of scope return result;}