// -*- mode:common-lisp; package: mma; -*- // LTD: Function PROVIDE not yet implemented. provide(#"ucons1"); #f; // LTD: Function LOAD not yet implemented. load("hash.fasl"); // (c) 1990, 1991, Richard J. Fateman // (c) 1994 Richard J. Fateman "(in-package mma)"; // alternative to ucons1 file of 1990, 91. using new hash table extensions // in Allegro 4.2 ++ (must have patch file hash.fasl installed) // non-standard hash table feature used below // LTD: No macros. #"eq-hash"; define method car-cdr-eq (key1, type, #key key2) if (type) // this is the hash-code for a single cons logxor(eq-hash(head(key1)), eq-hash(tail(key1))); else // this is the test to see if two conses have eq cars and eq cdrs eq-hash(head(key1)) == eq-hash(head(key2)) & eq-hash(tail(key1)) == eq-hash(tail(key2)); end if; end method car-cdr-eq; define variable *uniq-table* = make(, test: car-cdr-eq); define variable *uniq-atom-table* = make(
, test: \==); define method uniq (x) // Return a canonical representation that is EQUAL to x, // such that (equal x y) => (eq (uniq x) (uniq y)) select (x by instance?) fixnum | symbol => x; atom => *uniq-atom-table*[x] | (*uniq-atom-table*[x] := x); cons => ucons(uniq(head(x)), // this could check in // *uniq-table* first... uniq(tail(x))); end select; end method uniq; define variable *fakecons* = #(#"car" . #"cdr"); define method ucons (x, y) // Unique cons: (eq (ucons x y) (ucons x y)) is always true. let temp = *fakecons*; let tt = *uniq-table*; begin head(temp) := x; tail(temp) := y; end; let _that = #f; if (_that := tt[temp]) _that; // If already there, great. else tt[temp] := temp; *fakecons* := pair(#"car", #"cdr"); temp; end if; end method ucons; define method umapcar (f, x) if (empty?(x)) #f; else ucons(f(head(x)), umapcar(f, tail(x))); end if; end method umapcar; // LTD: No macros. #"ulist"; define method uappend (r, s) if (empty?(r)) s; else ucons(head(r), uappend(tail(r), s)); end if; end method uappend;