; -*- Scheme -*-
;
; $Id: string55.scm,v 1.1 1998/03/16 08:00:01 foner Exp $

;+doc
; procedure: string:diff
; arguments: a b
; signature: string x string -> int
;
; This is an implementation of a function suggested by
; Dan Bernstein <brnstnd@kramden.acf.nyu.edu> in alt.lang.cfutures as part
; of his `strinf' (infinite length strings) library.   The description
; Dan gives is :-
;
;  int strinfdiff(sf,tf) returns 0 if sf and tf are the same, -1 if sf is
;  a prefix of tf, -2 if it is not a prefix but is strictly smaller
;  (compared in dictionary order with individual chars unsigned), 1 if tf
;  is a prefix of sf, and 2 if tf is smaller than sf but not a prefix.
;-doc

(define string:diff
  (lambda (sf tf)
    (let ((sfl (string-length sf))
	  (tfl (string-length tf)))
      (let ((end-pos (min sfl tfl)))
	(let loop ((pos 0) (pc 0))
	  (if (= end-pos pos)
	      (cond ((< sfl tfl) (if (zero? pc) -1 pc))
		    ((> sfl tfl) (if (zero? pc) 1 pc))
		    (else pc))
	      (loop (+ 1 pos)
		    (cond
		     ((char<? (string-ref sf pos) (string-ref tf pos))
		      (case pc
			((0) -2)
			((1) 2)
			(else pc)))
		     ((char>? (string-ref sf pos) (string-ref tf pos))
		      (case pc
			((0) 2)
			((-1) -2)
			(else pc)))
		     (else pc)))))))))

; The use of CASE suggest to me that there is there is a nice
; (algebraic) optimisation missing from the above that would
; potentially make this much more efficient.  Perhaps addition mod 3?

; eof
