pad

PAD Sequence Types

This document describes the sequence types available in PAD and how to generate them.

Basic Sequence Generation

{fibonacci rows=10}{$fibonacci} {/fibonacci}      # Fibonacci numbers
{prime rows=15}{$prime} {/prime}                  # Prime numbers
{sequence '1..10', name='n'}{$n} {/sequence}      # Range 1-10
{random minimal=1, maximal=100, rows=5}{$random} {/random}   # Random numbers
{list '5;2;8;1;9'}{$list} {/list}                 # Custom list

Character/Letter Ranges

{sequence 'A..Z', name='letter'}{$letter} {/sequence}   # Full alphabet
{sequence 'a..e', name='c'}{$c} {/sequence}             # a, b, c, d, e
{sequence '0..9', name='digit'}{$digit} {/sequence}     # Digits as strings

OEIS Integration (Online Encyclopedia of Integer Sequences)

{sequence 10, oeis=81}{$sequence} {/sequence}           # OEIS sequence A000081
{sequence 15, oeis=257360}{$sequence} {/sequence}       # OEIS sequence A257360

The A-number is written without its leading zeroes. The terms come from pad/sequence/types/oeis/oeis.sqlite, one row per A-number, read a sequence at a time - so a request that asks for one costs a lookup rather than the whole table. An A-number the table does not hold produces no terms. oeis/regenerate.php regenerates the table from the stripped bulk download published by oeis.org.

Loop with from/to Parameters

{sequence loop, from=11, to=30, name='i'}{$i} {/sequence}

What from and to count depends on how the type produces its terms - values for the ones that test candidates, positions for the ones that compute the nth term. rows always counts terms and stop always names a value. See PAD.md for which types are which.

Naming a Sequence

A name that is not a sequence type, a stored sequence or an action is reported as an error. It used to be answered with a plain 1, 2, 3, … counter, which looked enough like a sequence to be mistaken for one, so a typo went unnoticed:

{sequence prime, rows=5}{$sequence} {/sequence}     # the primes
{sequence prmie, rows=5}{$sequence} {/sequence}     # error: 'prmie' is not a sequence type, a store or an action

Names are written as they are spelled, on every machine: {Keep '1..10', prime}, {Flag:even} and sequence:Prime(3) are no tag, type or sequence, as on a file system that tells case apart.

Positional parameters

The parameters written without a name are read in the order written, each by what it stands beside:

Sequence Types (122)

Mathematical Sequences

Where a sequence is conventionally listed with a leading term for n = 0, PAD starts at n = 1 and does not produce it: lucas begins at 1 rather than 2, pell omits its leading 0, catalan and bell their leading 1, caterer its leading 1 and moserdebruijn its leading 0, and gould is shifted the same way - as are factorial, jacobsthal, motzkin, partition and derangement, whose n = 0 term stands at position 0, before the first a run makes. fibonacci, tribonacci, perrin, recaman, leonardo and narayana do include their n = 0 term. Every value produced is a genuine member either way - only where the listing starts differs.

Figurate Numbers

Filters

Other Sequences

Digits

digitSum, digitalRoot and reversal are functions of the position, from n = 1; narcissistic and automorphic are lists - all of them a PHP integer holds, so their membership tests are exact; evil and odious count the binary digits.

Number Theory

The terms of totient, divisors and sigma are a function of the position, from n = 1, and their membership tests - {keep totient} and the rest - ask whether some n gives the value, which for totient and sigma is searched among the divisors of the value: the n can stand far past the value itself. The others are the numbers that have the property. The prime factors come from trial division and, past 10,000, Pollard’s rho through gmp, so a number of 19 digits is factored in well under a second.

Arithmetic Operations

Each takes a number as its parameter and applies it to the loop value, so they are most often used as plays over another sequence - {make multiply=3} - rather than generated on their own. A parameter that is not a number is reported rather than passed on, divide and multiple will not take a zero, and chance needs 1 or more.

Bitwise Operations

These work on the bits of the loop value and the parameter, not on true and false - and=3 gives 1, 2, 3, 0, 1, 2, 3, 0, which is n AND 3 rather than a logical answer. The four that complement their result run negative.

The arithmetic and bitwise types, eval and loop make a term at every position a run gives them, 0 and below included - {sequence add=3, from=0} is 3, 4, 5 - but their membership tests, which keep, remove and flag ask, count the positions from 1, where a run starts by default: a value is a member when a position of 1 or more makes it, so {sequence '3;4', flag, add=3} flags 0 1, and the 3 that position 0 made is none. multiple is the exception: it walks the values themselves, as step does, and its test takes every multiple of N, 0 and the negative ones included - {sequence '-6..3', keep, multiple=3} is -6, -3, 0, 3, where multiply=3 keeps 3 alone. A play over another sequence’s terms - {make add=3} - is arithmetic on whatever value it is handed.

Generation

Storing and Retrieving Sequences

IMPORTANT: Store names cannot be the same as action names (e.g., can’t use push='first' because first is an action).

Nor the name of something the page made - an array of the page, a {data}, {content}, {bool}, {define}, {macro} or a select table: push= (or a single tag’s name=) is refused under the strict check - “the store name ‘x’ is already an array of the page” - and a pair that only names its loop keeps no store. A value the request brought under the name (?nums[]=1) is no array the page made, and gives way to the store; so the refusal covers a name the page made itself that the request did not also bring - {set $primes = ['1']} before push='primes' is refused, with ?primes[]=1 in the request the same list is taken for the request’s and the store takes the name.

{sequence '1..10', push='mySeq'}           # Store sequence
{pull:mySeq}{$sequence} {/pull:mySeq}      # Retrieve and iterate

# Use pull: prefix to avoid naming conflicts with app tags
{sequence 5, push='nums'}
{pull:nums} {$sequence} {/pull:nums}

Sequence Tags

The sequence tags (resume, pull, keep, remove, flag, make) operate on stored sequences:

{sequence 5, push='mySeq'}           # Create and store sequence
{resume add=10}                       # Transform: add 10 to each value
{resume reverse}                      # Transform: reverse order
{pull:mySeq} {$sequence} {/pull:mySeq}  # Iterate stored sequence

Note: {resume} applies transformations to stored sequences. Use {continue} for skipping iterations (like PHP’s continue).

Sequence Variable Access

Use named sequences instead of level-based access:

{sequence 5, name='n'}
  {$n}                    # Correct - use named variable
{/sequence}

{sequence 5}
  {$sequence@-1}          # Avoid - level-based access can be fragile ({$-1} is no field)
{/sequence}

Named vs Unnamed Sequences

Always prefer named sequences for clarity:

{sequence 5, name='i'}
  {$i}                  # Clear, explicit
{/sequence}

{sequence '1..3', name='row'}
  {sequence '1..4', name='col'}
    ({$row},{$col})
  {/sequence}
{/sequence}

Special Syntax Rules

In an expression, sequence:<type>(n) is the nth term:

{echo '' | sequence:fibonacci(8)}     13 - the eighth Fibonacci number
{echo '' | sequence:prime(8)}         19
{if sequence:square(6) eq 36}...      the term reads as a value
{echo '' | sequence:add(3, 10)}       13 - a second argument is the type's parameter: add=10
{echo '' | sequence:prime(3, 'abc')}  error - prime takes no parameter

The action half of the same prefix - sequence:sum([1,2,3]) - answers with a list instead, because a list is what an action produces; {echo '' | sequence:sum([1,2,3]) . ''} prints it (6), where a pipe that ends on the list itself prints nothing. A value piped in without arguments is the call’s argument: {echo 5 | sequence:fibonacci} is the fifth term, 3, and ([1,2,3] | sequence:sum) . '' is 6. Numbers written one after another are the values too, for an action that takes no count and no store to act with: sequence:sum(1, 2, 3) is the sum of the three and sequence:sort(3, 1, 2) sorts them, where sequence:first(5, 2) reads the 2 as its count; a parameter given to an action that takes none - sequence:sum([1, 2], 3) - is an error under the strict check.

Some sequences need sequence: prefix:

{sequence:repeat 42, rows=5}{$repeat}{/sequence:repeat}
{sequence:even rows=10}{$even}{/sequence:even}

Chance sequence needs a numeric parameter:

{chance 4, rows=15}{$chance}{/chance}    # 1-in-4 chance (not {chance rows=15})

See Also