[m-dev.] Re: pragma fact_table
David Matthew OVERTON
dmo at students.cs.mu.oz.au
Thu Feb 27 13:33:13 AEDT 1997
Hi Fergus,
I've left the non-negative stuff in for now. I didn't see much point
in changing it while there is still disagreement about whether
negative hash values should be allowed.
David.
Estimated hours taken: 2
Add new predicate `float__hash' to the standard library for computing a
non-negative integer hash value for a float.
Add a C function to the runtime to do the actual hashing. This
function is in the runtime so that it can be called from both
the library and from C code generated for `pragma fact_table'
indexing.
library/float.m
Add a new predicate `float__hash' that calls the runtime
function `hash_float()'.
library/float.nu.nl
Add a new predicate `float__hash'. Note: this one computes a
different hash value to the one in `float.m'.
runtime/Mmakefile
Add `mercury_float.c' to the list of C files.
runtime/mercury_float.h
Add a declaration for `hash_float()'.
runtime/mercury_float.c
Add new file `mercury_float.c' for runtime code related to
floats.
Add a new function `hash_float()' for hashing floats.
Index: library/float.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/float.m,v
retrieving revision 1.20
diff -u -r1.20 float.m
--- 1.20 1996/07/26 06:00:14
+++ float.m 1997/02/26 07:08:23
@@ -156,7 +156,15 @@
:- mode float__epsilon(out) is det.
%---------------------------------------------------------------------------%
+% Compute a non-negative integer hash value for a float.
+% Note: the hash value computed is different to that computed in the
+% Prolog code in float.nu.nl.
+:- pred float__hash(float, int).
+:- mode float__hash(in, out) is det.
+
+%---------------------------------------------------------------------------%
+
:- implementation.
:- import_module int, require.
@@ -288,4 +296,12 @@
:- pragma(c_code, float__epsilon(Eps::out), "Eps = MERCURY_FLOAT_EPSILON;").
%---------------------------------------------------------------------------%
+
+:- pragma c_code(float__hash(F::in, H::out), will_not_call_mercury, "
+
+ H = hash_float(F);
+
+").
+
+%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
Index: library/float.nu.nl
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/float.nu.nl,v
retrieving revision 1.3
diff -u -r1.3 float.nu.nl
--- 1.3 1996/11/24 14:25:39
+++ float.nu.nl 1997/02/27 02:05:50
@@ -49,4 +49,19 @@
float__epsilon(2.2204460492503131e-16).
+ % Note: This hash function is different to the one defined in
+ % float.m.
+float__hash(Float, Hash) :-
+ float__abs(Float, Abs),
+ ( Abs = 0.0 -> Abs2 = 1e-15 ; Abs2 = Abs ),
+ math__ln(Abs2, Log),
+ math__ceiling(Log, TruncLog),
+ math__exp(TruncLog, Pow),
+ Float2 is Abs2 / Pow * 2147483647.0, % 2147483647 = (2^31)-1
+ float__truncate_to_int(Float2, N1),
+ float__abs(TruncLog, Log2),
+ float__truncate_to_int(Log2, N2),
+ Hash0 is N1 ^ N2,
+ int__abs(Hash0, Hash).
+
%-----------------------------------------------------------------------------%
Index: runtime/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- 1.2 1997/02/19 05:47:54
+++ Mmakefile 1997/02/26 07:04:22
@@ -40,7 +40,7 @@
MOD_OS = $(MOD_CS:.c=.o)
ORIG_CS = deep_copy.c dlist.c dummy.c label.c \
memory.c misc.c regs.c table.c timing.c prof.c prof_mem.c \
- spinlock.c
+ spinlock.c mercury_float.c
ORIG_OS = $(ORIG_CS:.c=.o)
OBJS = $(MOD_OS) $(ORIG_OS)
# OBJS = engine.o wrapper.o call.o \
Index: runtime/mercury_float.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_float.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_float.h
--- 1.3 1997/02/12 02:15:50
+++ mercury_float.h 1997/02/26 06:56:02
@@ -72,4 +72,8 @@
#endif /* not BOXED_FLOAT */
+/* hash_float() is defined in mercury_float.c */
+
+Integer hash_float(Float);
+
#endif /* not MERCURY_FLOAT_H */
===================================================================
new file: runtime/mercury_float.c
===================================================================
/*
** Copyright (C) 1996-1997 University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
#include "imp.h"
#include "conf.h"
/*
** The function `hash_float()' is used by the library predicate `float__hash'
** and also for hashing floats for `pragma fact_table' indexing.
** It computes a non-negative Integer hash value for a Float.
*/
#ifndef BOXED_FLOAT /* sizeof(Float) <= sizeof(Integer) */
union FloatInteger {
Float f;
Integer i;
};
Integer
hash_float(Float f)
{
union FloatInteger fi;
/*
** Just in case sizeof(Float) < sizeof(Integer), initialise
** fi.i to 0 so we don't get garbage in the result.
*/
fi.i = 0;
fi.f = f;
return (fi.i >= 0 ? fi.i : -fi.i);
}
#else /* BOXED_FLOAT -- sizeof(Float) > sizeof(Integer) */
union FloatInteger {
Float f;
Integer i[sizeof(Float)/sizeof(Integer)];
};
Integer
hash_float(Float f)
{
union FloatInteger fi;
size_t i;
Integer h = 0;
fi.f = f;
for (i = 0; i < sizeof(Float)/sizeof(Integer); i++)
h ^= fi.i[i];
return (h >= 0 ? h : -h);
}
#endif /* BOXED_FLOAT */
More information about the developers
mailing list