context function 2: filter


filter:
    description:
        filter(operators, conditions) input-seq
        Filters the input sequence to only those elements that satisfy the operator/condition pair
        It is more powerful than the such-that[] operator, but probably slower
        NB: input-seq structure is now preserved

    examples:
        -- learn some knowledge
        is-food |bread> => |yes>
        is-food |cheese> => |yes>
        is-food |steak> => |yes>

        is-furniture |chair> => |yes>
        is-furniture |table> => |yes>
        is-furniture |stool> => |yes>
        is-furniture |lounge> => |yes>

        is-day-of-week |monday> => |yes>
        is-day-of-week |tuesday> => |yes>
        is-day-of-week |wednesday> => |yes>
        is-day-of-week |thursday> => |yes>
        is-day-of-week |friday> => |yes>
        is-day-of-week |saturday> => |yes>
        is-day-of-week |sunday> => |yes>

        -- now try some filters:
        -- filter all known kets to those that are furniture:
        filter(|op: is-furniture>, |yes>) rel-kets[*]
            |chair> + |table> + |stool> + |lounge>

        -- filter all known kets to those that are food:
        filter(|op: is-food>, |yes>) rel-kets[*]
            |bread> + |cheese> + |steak>

        -- filter all known kets to those that are days of the week:
        filter(|op: is-day-of-week>, |yes>) rel-kets[*]
            |monday> + |tuesday> + |wednesday> + |thursday> + |friday> + |saturday> + |sunday>


        -- an indirect filter example, first learn some knowledge:
        father |John> => |Fred>
        occupation |Fred> => |politician>

        father |Sam> => |Robert>
        occupation |Robert> => |doctor>

        father |Emma> => |Jack>
        occupation |Jack> => |nurse>

        -- find people that have a father with occupation nurse:
        -- NB: Note the ops: rather than op: to signify operator sequence rather than just an operator
        filter(|ops: occupation father>, |nurse>) rel-kets[*]
            |Emma>

        -- find people that have a father with occupation doctor:
        filter(|ops: occupation father>, |doctor>) rel-kets[*]
            |Sam>


        -- find people that have the father operator defined:
        -- which is very close in function to the rel-kets[father] operator
        filter(|op: father>, |*>) rel-kets[*]
            |John> + |Sam> + |Emma>

        -- filter to people that have a father with occupation of either doctor or nurse:
        filter(|ops: occupation father>, |doctor> + |nurse>) rel-kets[*]
            |Sam> + |Emma>

        -- filter to those that have a rule of any type that is doctor or nurse:
        -- NB: if rel-kets[*] is large, or supported-ops is large, this may be slow.
        filter(|*>, |doctor> + |nurse>) rel-kets[*]
            |Robert> + |Jack>


        -- Finally, filters can be easily chained.
        -- Eg, To find all kets that are human, American and are politicians:
        -- NB: will be faster if you apply the most strict condition(s) first.
        -- Eg, in this case, politician first, then American, then human.
        filter(|op: is-human>, |yes>) filter(|op: is-american>, |yes>) filter(|op: occupation>, |politician>) rel-kets[*]


        -- What if we want to find all the known words that are their own plural?
        -- first, load some knowledge about words and their plurals:
        load plural.sw3

        -- now the required operator:
        -- which returns the input ket if its' plural equals itself, else the empty ket |>
        equal-plural |*> #=> filter(|op: plural>, |_self>) |_self>

        -- now apply it to all known kets:
        equal-plural rel-kets[*]
            |fish> + |sheep> + |series> + |shrimp> + |species> + |swine> + |trout> + |tuna>

    see also:
        not-filter, such-that, rel-kets
        plural.sw3
Home