; Author: Tom M
; Description: Set operations
; $Id: plc,v 1.1 98/03/23 01:37:17 tommut Exp Locker: tommut $
; $Log:	plc,v $
; Revision 1.1  98/03/23  01:37:17  tommut
; Initial revision
; 

; take the intersection of two lists
( defun my-intersection ( list1 list2 )
  ( cond ( (equal (cdr list1) nil) ( cond ( (member (car list1) list2) list1 )))
         ( t ( cond ( (member (car list1) list2 ) 
                     ( cons (car list1) (my-intersection (cdr list1) list2 ) ))
                     ( t ( my-intersection ( cdr list1 ) list2 ))
            )
        )
  )
)
                 

; take the union of two lists
( defun my-union ( list1  list2 )
  ( cond  ((equal (cdr list1) nil ) 
           ( cond ( (member (car list1) list2 ) 
                    ( cons (car list1) (remove (car list1) list2 )))
                    (t ( cons (car list1) list2))
           ))
          (t( cond( (member (car list1 ) list2)
                    ( cons (car list1) (my-union (cdr list1) 
						 (remove (car list1) list2) )))
                  (t( cons (car list1) (my-union (cdr list1) list2 ) ))
            )
          )
  )
)


; take the difference of two lists
( defun my-difference ( list1 list2 )
  ( cond ( (equal list1 nil) list2 )
	 ( t (my-difference (cdr (my-intersection list1 list2))
			    (remove (car (my-intersection list1 list2))
				    (my-union list1 list2 )
			    )
	     )
	 )
  )
)

; takes in a list and returns a list with the elements fully reversed down to
; the lowest level

( defun fullrev ( list1 ) 
  ( cond ( ( atom list1 ) list1 ) 
  ( (listp( car list1 ) )  
	( append ( fullrev( cdr list1 ) ) (list ( fullrev (car list1 ) ) ) ))	
  ( t ( append ( fullrev ( cdr list1 ) ) ( list ( car list1 ) ) ))

  )))
)
  	

; remove all occurences of an element from a list
( defun my-remove ( element list1 ) 
  ( cond (( equal list1 nil ) nil)
         ((not ( equal element (car list1))) 
	  (cons (car list1) (my-remove element (cdr list1)))
         )
  	( t ( my-remove element (cdr list1))
	)
  )
)

; splice in first argument for the second arg into the third
; ie: sub-splice '(1 2) 'b '(a b c)) returns (a 1 2 c)
( defun sub-splice ( in out struct )
  ( cond ( (equal struct nil ) nil )
	 ( (listp (car struct) )
	   (cons ( sub-splice in out (car struct))
		 ( sub-splice in out (cdr struct))))
	 ( (equal out (car struct))
           (cond ( (atom in) 
		   ( cons in (sub-splice in out ( cdr struct ))))
	           ( t ( append in (sub-splice in out ( cdr struct )))
	  	   )
           )
	 )
         (t ( cons (car struct ) ( sub-splice in out ( cdr struct )))
         )
  )
  	
)