1. Go to this page and download the library: Download gosuperscript/axiom library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
gosuperscript / axiom example snippets
use Superscript\Axiom\Expression;
use Superscript\Axiom\Sources\Coerce;
use Superscript\Axiom\Sources\StaticSource;
use Superscript\Axiom\Types\NumberType;
$source = new Coerce(
type: new NumberType(),
source: new StaticSource('42'),
);
$program = (new Expression($source))->compile()->unwrap();
$program()->unwrap()->unwrap(); // 42 (as integer)
use Superscript\Axiom\Definitions;
use Superscript\Axiom\Expression;
use Superscript\Axiom\ReferencePath;
use Superscript\Axiom\Sources\InfixExpression;
use Superscript\Axiom\Sources\StaticSource;
use Superscript\Axiom\Types\NumberType;
use Superscript\Axiom\Types\RecordType;
// area = PI * radius * radius
$source = new InfixExpression(
left: new ReferencePath('PI'),
operator: '*',
right: new InfixExpression(
left: new ReferencePath('radius'),
operator: '*',
right: new ReferencePath('radius'),
),
);
$area = new Expression(
source: $source,
definitions: new Definitions(['PI' => new StaticSource(3.14159)]),
declarations: new RecordType(['radius' => new NumberType()]),
);
$area->parameters(); // ['radius']
$program = $area->compile()->unwrap(); // every node resolved and certified
$program->returns; // NumberType — a property, not a query
$program->references; // [new ReferencePath('radius')]
$program(['radius' => 5])->unwrap()->unwrap(); // ~78.54
$program(['radius' => 10])->unwrap()->unwrap(); // ~314.16
$program = $expression->compile()->unwrap();
$program->returns; // the inferred return type
$program->references; // declared inputs resolved by compilation
$program($bindings); // boundary + evaluation; Result<Option<mixed>, Throwable>
$gate->infer(); // Ok(BooleanType) — what does this return?
$gate->check(new BooleanType()); // certified
$diagnosis = $expression->diagnose();
$diagnosis->diagnostics; // list<TypeMismatch> — every refusal, in the order compilation met them
$diagnosis->references; // list<ReferencePath>, including unresolved reads
$diagnosis->returns; // the root type, or null where the root itself failed
$diagnosis->program(); // Ok(Program) iff there are no diagnostics
use Superscript\Axiom\Expression;
use Superscript\Axiom\ReferencePath;
use Superscript\Axiom\Sources\InfixExpression;
use Superscript\Axiom\Sources\StaticSource;
use Superscript\Axiom\Types\NumberType;
use Superscript\Axiom\Types\Optional;
use Superscript\Axiom\Types\OptionType;
use Superscript\Axiom\Types\RecordType;
use Superscript\Axiom\Types\StringType;
$turnover = new ReferencePath('customer', 'turnover');
$condition = new InfixExpression(
left: new InfixExpression($turnover, '*', new StaticSource(1.2)),
operator: '>',
right: new StaticSource(500000),
);
$gate = new Expression(
source: $condition,
definitions: $definitions,
declarations: new RecordType([
'customer' => new RecordType([
'turnover' => new NumberType(),
]),
]),
);
$program = $gate->compile()->unwrap();
$program(['customer' => ['turnover' => '600000']]);
// the BOUNDARY coerces '600000' → 600000 through the declared type
// before evaluation — certified programs never see raw garbage
$program(['customer' => ['turnover' => 'lots']]);
// Err(InadmissibleBinding): "binding [customer]: Property [turnover]: …"
// — aggregated and named before any evaluation
$program([]);
// Err(MissingRequiredInput): the customer root
declarations: new RecordType([
'excess' => new OptionType($monetary),
'comment' => new Optional(new StringType()),
])
$program([]); // Err(MissingRequiredInput): nobody has answered
$program(['excess' => null]); // Ok(None): answered, and the answer is "none"
$program(['excess' => '250']); // Ok(Some(250))
$failure = $expression->compile()->unwrapErr(); // (name + 1) * 2, name declared String
$failure->message; // '[+] expects Number and Number; got String and 1.'
$failure->path; // '$.children[0].node' — the inner +, not the outer *
$tier = new UnionType(new LiteralType('micro'), new LiteralType('small'));
$tier->assert('micro'); // Ok(Some('micro'))
$tier->assert('large'); // Err — not a member
new Coerce(new NumberType(), $rawLookupCell) // '42 ' → 42; the compiler takes Number on faith
new Ascription(new NumberType(), $unknownHostSource) // "trust me, this is a number" — and it's checked twice
new DefaultValue($optionalPremium, 0)
new DefaultValue($optionalTags, [])
new InfixExpression($optionalPremium, '??', new ReferencePath('standard_premium'))
use Superscript\Axiom\Definitions;
use Superscript\Axiom\Expression;
use Superscript\Axiom\ReferencePath;
use Superscript\Axiom\Sources\StaticSource;
use Superscript\Axiom\Types\NumberType;
use Superscript\Axiom\Types\Optional;
use Superscript\Axiom\Types\RecordType;
$expression = new Expression(
source: new ReferencePath('quote', 'turnover'),
definitions: new Definitions([
'version' => new StaticSource('1.0.0'),
]),
declarations: new RecordType([
'quote' => new RecordType([
'turnover' => new NumberType(),
'claims' => new Optional(new NumberType()),
]),
]),
);
$program = $expression->compile()->unwrap();
$program([
'quote' => [
'turnover' => 600000,
// 'claims' may be omitted
],
]);
// if quote.claims > 2 then 100 * 0.25 else 0
new MatchExpression(
subject: new StaticSource(true),
arms: [
new MatchArm(
new ExpressionPattern(
new InfixExpression(
new ReferencePath('quote', 'claims'),
'>',
new StaticSource(2),
),
),
new InfixExpression(new StaticSource(100), '*', new StaticSource(0.25)),
),
new MatchArm(new WildcardPattern(), new StaticSource(0)),
],
);
// match tier { "micro" => 1.3, "small" => 1.1, _ => 1.0 }
new MatchExpression(
subject: new ReferencePath('tier'),
arms: [
new MatchArm(new LiteralPattern('micro'), new StaticSource(1.3)),
new MatchArm(new LiteralPattern('small'), new StaticSource(1.1)),
new MatchArm(new WildcardPattern(), new StaticSource(1.0)),
],
);
use Superscript\Axiom\Execution\Annotated;
use Superscript\Axiom\Execution\Event;
use Superscript\Axiom\Execution\Observer;
final class AnnotationLog implements Observer
{
public array $annotations = [];
public function observe(Event $event): void
{
if ($event instanceof Annotated) {
$this->annotations[] = [
'source' => $event->node->sourceType,
'key' => $event->key,
'value' => $event->value,
];
}
}
}
$observer = new AnnotationLog();
$program = $expression->compile()->unwrap();
$result = $program->call(['radius' => 5], observer: $observer);
use Superscript\Axiom\Operators\Operator;
Operator::infix('-')
->identifiedBy('time.date.minus-period')
->takes(new DateType(), new PeriodType())
->returns(new DateType())
->evaluatesWith(fn (Date $d, Period $p) => $d->minus($p));
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.