! form.ax - utility predicates based on the form of expressions
! == - identity relation
(== % %).
! id - identity function
(id % %).
! -- Same as == but we think of id as the identity function from argument to
! a result, while == is an equivalence relation for 2 identical expressions.
! concat - concatenation function
! (concat )
(concat ($1) ($2) ($1 $2)).
!>>> This is called 'append' in traditional LP,
! but we use 'concat' to avoid confusion with 'append1':
! generalization of concat to >2 input arguments
(concat %arg1 %arg2 $args ($) ($res $))< ! adding an argument
(concat %arg1 %arg2 $args ($res)).
! concatenation of a sequence of sequences (1-argument case)
(concat () ()).
(concat (($) $seqs) ($ $concat))<
(concat ($seqs) ($concat)).
! Generalize other binary operators in this manner? (plus, and, etc.)
! from ho.ax:
(generalize concat ()).
! append1 - append one value to a sequence
(append1 ($) % ($ %)).
! front_append - append expression to front of a sequence
(fappend % ($) (% $)).
! last - last element in a sequence
(last ($ %) %).
! head - first element in a sequence
(head (% $) %).
! tail - rest of a sequence after its head
(tail (% $) ($)).
! in - expression is in a sequence
(in % ($1 % $2)).
!>>> This is called 'member' in traditional LP.
! insert - insert an expression at some (any) point in a sequence
(insert %x ($1 $2) ($1 %x $2)).
! reverse - reverse a sequence
(reverse () ()).
(reverse (% $) ($rev %))<
(reverse ($) ($rev)).
! zero_or_more - sequence is zero or more occurrences of an expression
(zero_or_more % ()).
(zero_or_more % (% $))< (zero_or_more % ($)).
! -- better name needed! closure?
! ldistr - distribute an element over the front of multiple sequences
(ldistr % () ()).
(ldistr % (($) $seqs) ((% $) $seqs'))<
(ldistr % ($seqs) ($seqs')).
! -- or could use higher-order definition:
(ldistr $args)<
((1* fappend) $args).
! distr - distribute a sequence of elements over the fronts of sequences
! (Note that this is same as fappend*, once we define the * mapping
! (which needs distr in its definition!).)
(distr () () ()).
(distr (%el $els) (($seq) $seqs) ((%el $seq) $seqs'))<
(distr ($els) ($seqs) ($seqs')).
! turn relation into * that applies to sequences of arguments
((` ($rel '*')) $nulls)< (zero_or_more () ($nulls)). ! empty arg sequences
((` ($rel '*')) $argseqsx)< ! non-empty arg sequences
((` ($rel '*')) $argseqs),
((` ($rel)) $args), ! relation to be mapped
(distr ($args) ($argseqs) ($argseqsx)).
! all_subsets - set of all subsets of a set (sequence)
! (all_subsets ( ... ))
! -- note that element order is preserved
! -- note that we don't eliminate duplicate subsets (in case some original
! set elements are the same)
! -- Better name needed to reflect that these are all subsets of elements
! from the original sequence given in their original order.
(all_subsets () (())).
(all_subsets (% $) ($w% $w/o%))<
(all_subsets ($) ($w/o%)),
(ldistr % ($w/o%) ($w%)).
!/
examples:
(all_subsets () (())) -- just the empty sequence itself
(all_subsets (a) ((a) ()))
(all_subsets (a b) ((a b) (a) (b) ()))
(all_subsets (a b c) ((a b c) (a b) (a c) (a) (b c) (b) (c) ()))
...
!\
! insert_between - insert an expression between each element of a sequence
! (We do not insert before first element or after last.)
(insert_between %x () ()). ! no insertion here
(insert_between %x (%) (%)). ! or here
(insert_between %x (%' % $) (%' %x $'))< ! here's where we insert
(insert_between %x (% $) ($')).
! =length - two sequences are equal length
(=length () ()).
(=length (%1 $1) (%2 $2))<
(=length ($1) ($2)).
! `' - "constant" or "quote" function
((`' %) %ignored %). ! result comes from the function, argument is ignored