Full Finite-State Automata Grammar

This is the grammar used to parse the simple example shown, and other more complex, many-state diagrams, not shown. This grammar uses specialized Lisp functions, appended the end of this grammar, to describe the detailed geometrical arrangement of the component of arrowheads.


(setf 
          
 *grammar*    ; a grammar object
 
 (defgrammar
      
   ;;; **********  < Finite Automato >  *************
   ( FA -> Init-state  Transitions  Final-states 
        (Transitions)  (Final-states)  (Init-state) ) ;

   ;;; **********  < Transitions > *************
   ( Transition -> A-state_1  Labeled-arrow  A-state_2 
      (Labeled-arrow)
      (A-state_1  (touch (leave-pt (arrow Labeled-arrow)) '?))
      (A-state_2  (touch (reach-pt (arrow Labeled-arrow)) '?)) ) ;

   ( Transitions -> set ( Transition ) ) ;
   
   ;;; **********  < Labeled-arrow > *************
   ( Label -> Text
     (Text :constraints  (numeric-textp Text)) ) ;
   
   ( Labeled-arrow -> Arrow Label 
     (Arrow) 
     (Label  (touch  Arrow '?)
             :select (min (distance (center Label) (arrow-back Arrow)))) ) ;

 ;;; **********  < Arrow >  *************
   ( Arrow -> Arrow-back  Arrow-head
     (:additional-slots (leave-pt . (get-leave-pt self))
                        (reach-pt . (pt (arrow-head self))))
     (Arrow-head)
     (Arrow-back   (extends (touch (pt arrow-head) '?))
                   :select (min (distance (list (left-endpoint arrow-back) (right-endpoint arrow-back))
                            (pt arrow-head)))) ) ;
   
   ;;; **********  < Arrow-head >  *************
   ( Arrow-head -> Short-line_1  Short-line_2
     (:additional-slots  (pt . (get-arrow-head-pts self 'common-pt))) 
     (Short-line_1)
     (Short-line_2  (touch Short-line_1 '?)
             :constraints
             (different Short-line_1  Short-line_2)
             (left  (center Short-line_1)  (center Short-line_2) :strictly t)
             (same-length (line Short-line_1) (line Short-line_2) :ratio 1.7)
             (< (distance (endpts short-line_1) (endpts short-line_2)) 
                (/ (a-length (line Short-line_1)) 5.0))) ) ;  ~ 40

    ;;; **********  < Arrow-back > *************
   ( Arrow-back -> Line 
     (:additional-slots  (left-endpoint  . (left-endpoint  (Line  self)))
                         (right-endpoint . (right-endpoint (Line  self))))
     (:constraints  (long Line :ratio 22)) ) ;

   ( Arrow-back ->  Curve-back
     (:additional-slots  (left-endpoint  . (left-endpoint  (Curve-back self)))
                         (right-endpoint . (right-endpoint (Curve-back self))))) ;

   ( Curve-back -> set ( Curve ) (:constraint connected) ) ;
   
   ;;; **********  < Short-line > *************
   ( Short-line -> Line
     (:additional-slots  (endpts . (endpoints (Line self)))
                         ;(length . (a-length (Line self)))
                         ) ;; add length
     (:constraints (short Line)) ) ;

   ;;; **********  < A-state > *************
   ( A-state -> Circle  Text
     (Circle :constraints (not (contained Circle (some* [circle]))))
     (Text   (contain Circle '?)) ) ;

   ;;; **********  < Final-states >  *************
   ( Final-state -> A-state 
      (A-state  
       :constraints (contain (circle  A-state) (some* [circle] :in (touch '? A-state)))) ) ;
   
   ( Final-states -> set ( Final-state ) ) ;

   ;;; **********  Init-state  *************
   ( Init-state -> A-state  Arrow
     (A-state)
     (Arrow  (touch A-state '?)
      :constraints  (touch (reach-pt Arrow) A-state) 
                    (null (some* [a-state] :in (touch '? (leave-pt Arrow))))) ) ;
   ) 
 )


;;; -------------------------------------------
;;;         Non supported functions
;;; -------------------------------------------
          
(defmethod left-endpoint ((go curve-back)) 
  (apply #'left-point (curve-cluster-endpoints (value go))))

(defmethod right-endpoint ((go curve-back)) 
  (apply #'right-point (curve-cluster-endpoints (value go))))

;;;
(defmethod distance ((pt a-point) (go arrow-back<1>) &key (min-max 'min))  ; <1> the first alternative in the grammar.
  (distance pt (line go)))


(defmethod distance ((pt a-point) (go arrow-back<2>) &key (min-max 'min)) 
  (pt-curve-cluster-dist pt (value (curve-back go))))


;;; -------------------------------------------
(defmethod get-arrow-head-pts ((ob arrow-head) type)
  
  (let* ((line1-end-pts (make-array '(2) 
                                    :initial-contents (a-line-terminators (line (short-line_1 ob)))))
         (line2-end-pts (make-array '(2) 
                                    :initial-contents (a-line-terminators (line (short-line_2 ob)))))
         (distance-array (make-array '(2 2) :initial-element nil)))
      
    (dotimes (i 2)
    (dotimes (j 2)
      (setf (aref distance-array i j) 
            (distance (aref line1-end-pts i) (aref line2-end-pts j)))))
    
    (let (common-pt f-p1 f-p2 min id-1 id-2);
      ;; common-pt corresponds to the "corner" point of the arrow head
      
      (setf min (aref distance-array 0 0))
      
      (dotimes (i 2)
      (dotimes (j 2)
        (when (<= (aref distance-array i j) min) 
          (setf min (aref distance-array i j))
          (setf id-1 i)
          (setf id-2 j))))
      
    (setf common-pt (aref line1-end-pts id-1))
    (setf f-p1 (aref line1-end-pts (- 1 id-1)))
    (setf f-p2 (aref line2-end-pts (- 1 id-2)))
    
    (cond ((equal type 'all) (list common-pt f-p1 f-p2))
          ((equal type 'common-pt) common-pt)
          ((equal type 'p1) f-p1)
          (t f-p2)))))

;;;
(defun get-head-pt (arrow-head)
  )

;;;
(defun get-leave-pt (arrow)
  (let ((pt (pt (arrow-head arrow))))
    
    (if (> (distance pt (left-endpoint  (arrow-back arrow)))
           (distance pt (right-endpoint (arrow-back arrow))))
    (left-endpoint (arrow-back arrow))
    (right-endpoint (arrow-back arrow)))
    ))

 

Back to automata example

Back to Index page