)if false
\documentclass{article}
\usepackage{axiom}
\usepackage{url}
\begin{document}
\title{HashState}
\author{Waldek Hebisch and Ralf Hemmecke}
\maketitle
\begin{abstract}
This domain is intended to support the computation of hash values.
\end{abstract}

\tableofcontents

\section{A simple hash value container}

The main idea for the domain HashState was given by Waldek Hebisch
in a mail to \url{fricas-devel}, see
\url{https://groups.google.com/d/msg/fricas-devel/ofHadCkfdC8/SZGZbAai7ygJ}.

It follows the text part of the message.
\begin{verbatim}
To : fricas-devel@googlegroups.com
Date : Tue, 10 Nov 2009 04 : 19 : 59 +0100 (CET)
From : Waldek Hebisch <hebisch@math.uni.wroc.pl>

Below is may proposal how to handle hashing.  Basically the
main point is that SingleInteger may be inconvenient as _state_
during hashing process -- one has to be careful to avoid overflow
and since SingleInteger may have limited number of bits mixing
must be extra good.  Bigger state may allow much easier update.

So I propose the following protocol : we first create a fresh
HashState.  Then we walk through data structure updating state.
Finally we reduce state to a SingleInteger.  The implementation
below is intended as a starting point -- I use SingleInteger
as representation of HashState and 'combine' function is
probably slow and it is not clear how good it mixes.  But
if we stick to the protocol we can change representation
later and add better 'combine'.  Anyway, given definitions
in HashState and SetCategory we can start to modify domains
like the included example of PrimitiveArray and Integer.
\end{verbatim}

\section{Implementation}

The domain HashState is simply calling the respective lisp macros.

)endif

)abbrev domain HASHSTAT HashState
++ Description: This domain supports incremental computation of hash
++ values.
HashState() : with
    new : () -> %
      ++ new() return a new HashState.
    update! : (%, SingleInteger) -> %
      ++ update!(hs, x) computes new values of HashState from hs
      ++ and x and might destructively operate on its first argument.
    value : % -> SingleInteger
      ++ value(x) returns a non-negative SingleInteger value
      ++ corresponding to x.
  == add
    -- These two macros are necessary to distinguish between Rep and \%.
    rep x ==> (x@%) pretend Rep
    per x ==> (x@Rep) pretend %

    I ==> SingleInteger

    Rep ==> Integer
    new() : % == per HASHSTATEBASIS$Lisp
    value(hs : %) : I == (HASHSTATEMAKEFIXNUM(hs)$Lisp) pretend I
    update!(hs : %, i : I) : % == per HASHSTATEUPDATE(hs, i)$Lisp
    modulo(hs : %, i : I) : I == (HASHSTATEMOD(hs, i)$Lisp) pretend I

)if false

\section{Usage}

The general pattern to use HashState is given by the default implementation
of the hash function in SetCategory, see \url{src/algebra/catdef.spad}.

<<usage : SetCategory>>=
hash(s : %) : SingleInteger ==
    value(hashUpdate!(new()$HashState, s))$HashState
@

Instead of implementing
\begin{verbatim}
hash : % -> SingleInteger
\end{verbatim}
a domain should rather implement a function \texttt{hashUpdate!} by
means of the \texttt{update!} function above.

\end{document}
)endif
