[racket] fuzzy set representation in Racket

From: Rian Shams (rian.shams at gmail.com)
Date: Mon Aug 26 21:09:16 EDT 2013

Thank you, a fuzzy-set-library is exactly what I am looking for. Initially
I tried to create this library using the methodology you describe from the
chapter on sets in "The Little Schemer," but after discovering structs in
Racket I switched over. More recently I have been trying to emulate the
set.rkt file that is provided in collect, but am finding this overwhelming
(at least for the time being).

In order to define the fuzzy set operators I believe I would need
fuzzy-set? and then selectors that correspond to each field. I am unclear
as to why fuzzy-set? doesn't seem to exist and am not sure how to create
fuzzy-set-first and fuzzy-set-rest (along with all of the other operators
such as fuzzy-union, fuzzy-intersect , etc...) without having a fuzzy-set?
made available.

My question is given:

(fuzzy-set
  (fuzzy-element 'a 1)
  (fuzzy-element 'b .2)
  (fuzzy-element 'c .2)
  (fuzzy-element 'd .3)))

in the way you defined fuzzy-set above, how do you create the function
fuzzy-set? and how do you create fuzzy-first and fuzzy-rest ?

Thanks,
Rian

On Aug 23, 2013, at 8:02 PM, Matthias Felleisen <matthias at ccs.neu.edu>
wrote:


Here is one more alternative:

#lang racket

;; you can move the body of this module into a '#lang racket' file called
fuzzy-set-library.rkt
(module fuzzy-set-library racket
  ;; rename-out is an elegant version of the let()/define-values trick in
Realm of Racket
  (provide (rename-out (fuzzy-set0 fuzzy-set)) (struct-out fuzzy-element))

  (struct fuzzy-element (val degree) #:transparent)
  ;; FE = (fuzzy-element Any [0,1))

  (struct fuzzy-set (vals)
    #:transparent
    #:guard
    ;; [List-of FE] -> Fuzzy-set
    (lambda (le type-name)
      (define-values (members _)
        (for/fold ((s '()) (keys '())) ((x le))
          (unless (fuzzy-element? x)
            (error type-name "fuzzy-element expected, given: ~e" x))
          (define k (fuzzy-element-val x))
          (if (member k keys)
              (values s keys)
              (values (cons x s) (cons k keys)))))
      (apply set members)))
  ;; FuzzySet = (fuzzy-set [Set-of FE])

  (define (fuzzy-set0 . x) ;; <--- this means take as many arguments as
there are, as a list
    (fuzzy-set x))

  ;; add
  ;; -- fuzzy-add-element
  ;; -- fuzzy-union
  ;; etc.
  )

;; this could be a '#lang racket' file too
(module fuzzy-set-client racket
  ;; then you replace this with the usual require
  (require (submod ".." fuzzy-set-library))

  (fuzzy-set
   (fuzzy-element 'a .1)
   (fuzzy-element 'b .2)
   (fuzzy-element 'c .3)
   (fuzzy-element 'a .3)))

;; drop this, it exists to test
(require 'fuzzy-set-client)



On Aug 23, 2013, at 3:49 PM, Rian Shams wrote:

Hello All,

My name is Rian and I am a new Racket user and a novice programmer (Racket
is my first language). First let me say that I am very grateful for the
resources available online and the books, HTDP and Realm of Racket. I find
your teaching methods very clear and as a result I am picking up Racket
faster than I originally thought.

I am a System Science graduate student whose primary research focus is on
Fuzzy Set Theory. A fuzzy set is a collection of distinct elements where
each element has a degree of membership associated with it.

The representation I am currently using for a fuzzy set is the following:
First I create a struct called fuzzy-element which consists of 2 fields;
the first is the name of the element and the second is the elements degree
of membership to the set which ranges from 0 to 1.

;; Data Definition

#lang racket

(struct fuzzy-element (member degree-of-membership)
  #:transparent
  #:guard (lambda (member degree-of-membership type-name)
            (cond
              [(not (and (number? degree-of-membership)
                         (<= 0 degree-of-membership 1)
degree-of-membership))
               (error type-name
                      "~e is not a number between 0 and 1"
                      degree-of-membership)]
              [else (values member degree-of-membership)])))

;; fuzzy-element is (fuzzy-element Symbol Number[0, 1])
;; interp. a fuzzy-element as a struct in which:
;;         -the first field is the member's name
;;         -the second field is the respective members degree of membership

Then I combine them with a list so what I have now is a list of fuzzy
elements.

;; ListOfFuzzyElement is one of:
;; - empty
;; - (cons fuzzy-element ListOfFuzzyElement)

The problem with this data definition is that it allows for duplicate
structs with the same field-1 elements.

What I am looking to create is

;; A Fuzzy-Set is one of:
;; - empty list
;; - (cons *distinct* fuzzy-element ListOfFuzzyElement)



Ideally the type of representation I would like to use should look like:

(fuzzy-set (fuzzy-element 'a .1)
               (fuzzy-element 'b .2)
               (fuzzy-element 'c .3)
               (fuzzy-element 'a .3))

-> (fuzzy-set (fuzzy-element 'a .1)
                   (fuzzy-element 'b .2)
                   (fuzzy-element 'c .3))

Upon evaluation, the last element, (fuzzy-element 'a .3) is deleted because
there already exists a member named 'a (fuzzy-element 'a .1). It should
work exactly like the built in "set" data type, except in this case it is a
set of structures that checks the first fields of all structures and
eliminates latter duplicates.

Any guidance on how to create fuzzy-set representation this way or if you
can suggest more concise and elegant methods I would be greatly
appreciative.

Thanks,
-- 
Rian Shams
____________________
 Racket Users list:
 http://lists.racket-lang.org/users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130826/7ed829ab/attachment-0001.html>

Posted on the users mailing list.