)abbrev domain REF Reference
++ Author: Stephen M. Watt
++ Basic Operations: deref, elt, ref, setelt, setref, =
++ Related Constructors:
++ Keywords:  reference
++ Description:  \spadtype{Reference} is for making a changeable instance
++ of something.

Reference(S : Type) : Type with
        ref   : S -> %
          ++  ref(n) creates a pointer (reference) to the object n.
        elt   : % -> S
          ++ elt(n) returns the object n.
        setelt! : (%, S) -> S
          ++ setelt!(n, m) changes the value of the object n to m.
        -- alternates for when bugs don't allow the above
        deref : % -> S
          ++ deref(n) is equivalent to \spad{elt(n)}.
        setref : (%, S) -> S
          ++ setref(n, m) same as \spad{setelt!(n, m)}.
        _=   : (%, %) -> Boolean
          ++ a=b tests if \spad{a} and \spad{b} are the same pointer/reference.
        if S has SetCategory then SetCategory

    == add
        Rep := Record(value : S)

        p = q        == EQ(p, q)$Lisp
        ref v        == [v]
        elt p        == p.value
        setelt!(p, v) == p.value := v
        deref p      == p.value
        setref(p, v) == p.value := v

        if S has SetCategory then
          coerce p ==
            prefix(message("ref"@String), [p.value::OutputForm])


)abbrev domain BOOLEAN Boolean
++ Author: Stephen M. Watt
++ Basic Operations: true, false, not, and, or, xor, nand, nor, implies
++ Related Constructors:
++ Keywords: boolean
++ Description:  \spadtype{Boolean} is the elementary logic with 2 values:
++ true and false

Boolean() : Join(OrderedSet, Finite, Logic, ConvertibleTo InputForm) with
    _not : % -> %
      ++ not n returns the negation of n.
    _and  : (%, %) -> %
      ++ a and b  returns the logical {\em and} of Boolean \spad{a} and b.
    _or  : (%, %) -> %
      ++ a or b returns the logical inclusive {\em or}
      ++ of Boolean \spad{a} and b.
    xor    : (%, %) -> %
      ++ xor(a, b) returns the logical exclusive {\em or}
      ++ of Boolean \spad{a} and b.
    nand   : (%, %) -> %
      ++ nand(a, b) returns the logical negation of \spad{a} and b.
    nor    : (%, %) -> %
      ++ nor(a, b) returns the logical negation of \spad{a} or b.
    implies : (%, %) -> %
      ++ implies(a, b) returns the logical implication
      ++ of Boolean \spad{a} and b.
    test : % -> Boolean
      ++ test(b) returns b and is provided for compatibility with the new compiler.
  == add
    nt : % -> %

    test a        == a pretend Boolean

    nt b          == (b pretend Boolean => false; true)
    true          == EQ(2, 2)$Lisp   --well, 1 is rather special
    false         == NIL$Lisp
    -- sample()      == true
    not b         == NOT(b)$Lisp
    _~ b          == NOT(b)$Lisp
    _and(a, b)    == AND(a, b)$Lisp
    _/_\(a, b)    == AND(a, b)$Lisp
    _or(a, b)     == OR(a, b)$Lisp
    _\_/(a, b)    == OR(a, b)$Lisp
    xor(a, b)     == (test a => nt b; b)
    nor(a, b)     == (test a => false; nt b)
    nand(a, b)    == (test a => nt b; true)
    a = b         == BooleanEquality(a, b)$Lisp
    implies(a, b) == (test a => b; true)
    a < b         == (test b => not(test a);false)

    import from Integer

    size()        == 2
    index i       ==
      even?(i::Integer) => false
      true
    lookup a      ==
      a pretend Boolean => 1
      2
    random()      ==
      even?(random(2)$Integer) => false
      true

    convert(x : %) : InputForm ==
      x pretend Boolean => convert('true)
      convert('false)

    coerce(x : %) : OutputForm ==
      x pretend Boolean => message "true"
      message "false"


)abbrev domain IBITS IndexedBits
++ Author: Stephen Watt and Michael Monagan
++ Date Created: July 86
++ Basic Operations: range
++ Related Constructors:
++ Keywords: indexed bits
++ Description: \spadtype{IndexedBits} is a domain to compactly represent
++ large quantities of Boolean data.

IndexedBits(mn : Integer) : BitAggregate() with
        -- temporaries until parser gets better
        Not : % -> %
            ++ Not(n) returns the bit-by-bit logical {\em Not} of n.
        Or : (%, %) -> %
            ++ Or(n, m)  returns the bit-by-bit logical {\em Or} of
            ++ n and m.
        And : (%, %) -> %
            ++ And(n, m)  returns the bit-by-bit logical {\em And} of
            ++ n and m.
    == add

        range : (%, Integer) -> Integer
          --++ range(j, i) returns the range i of the boolean j.

        minIndex u  == mn

        range(v, i) ==
          i >= 0 and i < #v => i
          error "Index out of range"

        coerce(v) : OutputForm ==
            t:Character := char "1"
            f:Character := char "0"
            s := new(#v, space()$Character)$String
            for i in minIndex(s)..maxIndex(s) for j in mn.. repeat
              s.i := if v.j then t else f
            s::OutputForm

        new(n, b)    == make_BVEC(n, bool_to_bit(b)$Lisp)$Lisp
        empty()      == make_BVEC(0, 0)$Lisp
        copy v       == copy_BVEC(v)$Lisp
        #v           == size_BVEC(v)$Lisp
        v = u        == equal_BVEC(v, u)$Lisp
        v < u        == greater_BVEC(u, v)$Lisp
        _and(u, v)   == (#v = #u => and_BVEC(v, u)$Lisp; map("and", v, u))
        _or(u, v)    == (#v = #u => or_BVEC(v, u)$Lisp; map("or", v, u))
        xor(v, u)    == (#v = #u => xor_BVEC(v, u)$Lisp; map("xor", v, u))
        setelt!(v : %, i : Integer, f : Boolean) ==
            SETELT_BVEC(v, range(v, i - mn), bool_to_bit(f)$Lisp)$Lisp
        elt(v : %, i : Integer) ==
            bit_to_bool(ELT_BVEC(v, range(v, i - mn))$Lisp)$Lisp

        Not v        == not_BVEC(v)$Lisp
        And(u, v)    == (#v = #u => and_BVEC(v, u)$Lisp; map("and", v, u))
        Or(u, v)     == (#v = #u => or_BVEC(v, u)$Lisp; map("or", v, u))

)abbrev domain BITS Bits
++ Author: Stephen M. Watt
++ Basic Operations: And, Not, Or
++ Related Constructors:
++ Keywords: bits
++ Description:  \spadtype{Bits} provides logical functions for Indexed Bits.

Bits() : Exports == Implementation where
  Exports == BitAggregate() with
    bits : (NonNegativeInteger, Boolean) -> %
        ++ bits(n, b) creates bits with n values of b
  Implementation == IndexedBits(1) add
    bits(n, b)    == new(n, b)

--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
