[PD-cvs] externals/moocow/gfsm/src Makefile.am, NONE, 1.1 atom_alphabet.c, NONE, 1.1 atom_alphabet.h, NONE, 1.1 gfsm-help.pd, NONE, 1.1 gfsm-help.tfst, NONE, 1.1 gfsm_alphabet-help.pd, NONE, 1.1 gfsm_automaton-help.pd, NONE, 1.1 gfsm_markov-help.pd, NONE, 1.1 gfsm_markov.pd, NONE, 1.1 gfsm_state-help.pd, NONE, 1.1 lkpin.tfst, NONE, 1.1 lkptest.tfst, NONE, 1.1 pd_algebra.c, NONE, 1.1 pd_alphabet.c, NONE, 1.1 pd_alphabet.h, NONE, 1.1 pd_automaton.c, NONE, 1.1 pd_automaton.h, NONE, 1.1 pd_gfsm.c, NONE, 1.1 pd_gfsm.h, NONE, 1.1 pd_io.c, NONE, 1.1 pd_io.h, NONE, 1.1 pd_state.c, NONE, 1.1 pd_state.h, NONE, 1.1 test-alphabet.pd, NONE, 1.1 test-alphabet2.pd, NONE, 1.1 test-automaton.pd, NONE, 1.1 test-automaton2.pd, NONE, 1.1 test-fsm.pd, NONE, 1.1 test-markov.pd, NONE, 1.1 test-state.pd, NONE, 1.1 test-state2.pd, NONE, 1.1 test.lab, NONE, 1.1 test.tfst, NONE, 1.1 test2.lab, NONE, 1.1 test2.tfst, NONE, 1.1 test3.tfst, NONE, 1.1

Bryan Jurish mukau at users.sourceforge.net
Thu Feb 2 13:44:31 CET 2006


Update of /cvsroot/pure-data/externals/moocow/gfsm/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23065/src

Added Files:
	Makefile.am atom_alphabet.c atom_alphabet.h gfsm-help.pd 
	gfsm-help.tfst gfsm_alphabet-help.pd gfsm_automaton-help.pd 
	gfsm_markov-help.pd gfsm_markov.pd gfsm_state-help.pd 
	lkpin.tfst lkptest.tfst pd_algebra.c pd_alphabet.c 
	pd_alphabet.h pd_automaton.c pd_automaton.h pd_gfsm.c 
	pd_gfsm.h pd_io.c pd_io.h pd_state.c pd_state.h 
	test-alphabet.pd test-alphabet2.pd test-automaton.pd 
	test-automaton2.pd test-fsm.pd test-markov.pd test-state.pd 
	test-state2.pd test.lab test.tfst test2.lab test2.tfst 
	test3.tfst 
Log Message:
initial cvs import

--- NEW FILE: pd_gfsm.h ---
/*=============================================================================*\
 * File: pd_gfsm.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

/*=====================================================================
 * Protos
 *=====================================================================*/
#ifndef PD_GFSM_H
#define PD_GFSM_H

/*----------------------------------------------------------------------
 * includes
 */
#include <m_pd.h>
#include <gfsm.h>

/*----------------------------------------------------------------------
 * structures and types
 */
typedef struct _pd_gfsm_dummy
{
  t_object            x_obj;
} t_pd_gfsm_dummy;


/*----------------------------------------------------------------------
 * setup routines
 */
void gfsm_setup(void);

#endif /* PD_GFSM_H */

--- NEW FILE: pd_gfsm.c ---
/*=============================================================================*\
 * File: pd_gfsm.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_gfsm.h>
#include <pd_alphabet.h>

#define USE_AUTOMATA

#ifdef USE_AUTOMATA
# include <pd_automaton.h>
# include <pd_state.h>
#endif

/*=====================================================================
 * Structures and Types
 *=====================================================================*/
static t_class *pd_gfsm_dummy_class;

/*=====================================================================
 * pd_gfsm_dummy
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_dummy: new()
 */
static void *pd_gfsm_dummy_new(void)
{
  t_pd_gfsm_dummy *x = (t_pd_gfsm_dummy *)pd_new(pd_gfsm_dummy_class);
  return (void *)x;
}

/*--------------------------------------------------------------------
 * pd_gfsm_dummy: free()
 */
static void pd_gfsm_dummy_free(t_pd_gfsm_dummy *x)
{}

/*--------------------------------------------------------------------
 * pd_gfsm_dummy: setup()
 */
void gfsm_setup(void)
{
  //-- banner
  post("");
  post("gfsm: finite state machine externals v%s by Bryan Jurish", PACKAGE_VERSION);
  //post("fsm: based on code by Helmut Schmid");

  //-- library
  pd_gfsm_alphabet_setup();
#ifdef USE_AUTOMATA
  pd_gfsm_automaton_setup();
  pd_gfsm_state_setup();
#endif

  //-- class (dummy)
  pd_gfsm_dummy_class = class_new(gensym("gfsm"),
				  (t_newmethod)pd_gfsm_dummy_new,
				  (t_method)pd_gfsm_dummy_free,
				  sizeof(t_pd_gfsm_dummy),
				  CLASS_DEFAULT,
				  A_NULL);
  
  //-- help symbol
  class_sethelpsymbol(pd_gfsm_dummy_class, gensym("gfsm-help.pd"));
}

--- NEW FILE: pd_alphabet.h ---
/*=============================================================================*\
 * File: pd_alphabet.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifndef _PD_GFSM_ALPHABET_H
#define _PD_GFSM_ALPHABET_H

#include <m_pd.h>
#include <gfsm.h>
#include <atom_alphabet.h>


/*--------------------------------------------------------------
 * pd_gfsm_alphabet
 */
typedef struct _pd_gfsm_alphabet_pd
{
  t_pd                 x_pd;
  t_symbol            *x_name;
  size_t               x_refcnt;
  gfsmAlphabet        *x_alphabet; //-- really a (gfsmPdAtomAlphabet*)
} t_pd_gfsm_alphabet_pd;


/*--------------------------------------------------------------
 * pd_gfsm_alphabet
 */
typedef struct _pd_gfsm_alphabet_obj
{
  t_object                x_obj;
  t_pd_gfsm_alphabet_pd  *x_alphabet_pd;
  t_outlet               *x_labout;
  t_outlet               *x_keyout;
} t_pd_gfsm_alphabet_obj;


/*--------------------------------------------------------------
 * pd_gfsm_alphabet: methods
 */
//-- finds pd_gfsm_alphabet named 'name', returns NULL if it doesn't exist
t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_find(t_symbol *name);

//-- finds pd_gfsm_alphabet named 'name', creating it if it doesn't exist
t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_get(t_symbol *name);

//-- releases one reference to pd_gfsm_alphabet named 'name', possibly freeing the pd_gfsm_alphabet
void pd_gfsm_alphabet_pd_release(t_pd_gfsm_alphabet_pd *x);

/*--------------------------------------------------------------
 * setup methods
 */
void pd_gfsm_alphabet_setup(void);


#endif /* _PD_GFSM_ALPHABET_H */

--- NEW FILE: test2.lab ---
<epsilon>	0
a	1
b	2
c	3
foo	42
x	1

--- NEW FILE: test-automaton.pd ---
#N canvas 31 7 974 447 10;
#X obj 13 7 gfsm;
#X obj 22 324 gfsm_automaton;
#X obj 22 359 print GFSM-1;
#X msg 26 70 automaton;
#X msg 24 29 automaton a1;
#X obj 16 91 s \$0-fsm;
#X obj 23 300 r \$0-fsm;
#X msg 153 75 size;
#X floatatom 237 34 5 0 0 0 - - -;
#X obj 237 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X floatatom 144 34 5 0 0 0 - - -;
#X msg 257 15 0;
#X msg 145 13 42;
#X floatatom 375 18 5 0 0 0 - - -;
#X msg 347 17 0;
#X floatatom 388 61 5 0 0 0 - - -;
#X floatatom 517 34 5 0 0 0 - - -;
#X floatatom 560 33 5 0 0 0 - - -;
#X floatatom 603 33 5 0 0 0 - - -;
#X floatatom 644 34 5 0 0 0 - - -;
#X obj 543 59 pack 0 0 0 0 0;
#X obj 494 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 494 57 t b b;
#X msg 569 7 0;
#X msg 495 105 add_arc \$1 \$2 \$3 \$4 \$5;
#X obj 144 98 s \$0-fsm;
#X obj 237 97 s \$0-fsm;
#X obj 349 121 s \$0-fsm;
#X obj 496 126 s \$0-fsm;
#X msg 104 148 load test.tfst;
#X msg 103 188 save tmp.tfst;
#X msg 229 148 load_bin test.gfst;
#X msg 250 304 save_bin tmp.gfst;
#X msg 26 202 print;
#X msg 22 179 clear;
#X msg 18 158 info;
#X obj 17 226 s \$0-fsm;
#X obj 88 246 s \$0-fsm;
#X obj 236 338 s \$0-fsm;
#X msg 437 170 complement;
#X msg 450 211 closure \$1;
#X floatatom 466 193 5 0 0 0 - - -;
#X obj 437 370 s \$0-fsm;
#X obj 16 132 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
-1 -1;
#X obj 450 193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 457 236 compose a2;
#X msg 462 264 concat a2;
#X obj 51 6 zexy;
#X obj 495 84 lister;
#X msg 25 48 automaton a2;
#X msg 464 291 determinize;
#X msg 469 319 difference a2;
#X msg 475 343 intersect a2;
#X obj 603 368 s \$0-fsm;
#X msg 598 148 invert;
#X msg 607 174 product a2;
#X msg 621 217 project \$1;
#X floatatom 638 196 5 0 0 0 - - -;
#X obj 619 198 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 631 269 reverse;
#X msg 631 296 rmepsilon;
#X msg 634 320 union a2;
#X msg 103 168 load test2.tfst;
#X msg 233 169 load_bin test2.gfst;
#X msg 238 190 load_bin test3.gfst;
#X obj 46 131 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
-1 0 1;
#X msg 246 74 root;
#X msg 237 51 root \$1;
#X floatatom 618 8 5 0 0 0 - - -;
#X msg 144 52 size \$1;
#X msg 349 37 final \$1;
#X obj 430 61 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X obj 365 79 pack 0 0;
#X msg 363 99 final \$1 \$2;
#X msg 637 343 renumber;
#X msg 252 282 load_bin tmp.gfst;
#N canvas 0 0 450 300 flags 0;
#X obj 26 67 s \$0-fsm;
#X msg 36 21 weighted \$1;
#X obj 19 21 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X msg 39 43 weighted;
#X obj 145 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X obj 155 65 s \$0-fsm;
#X msg 162 19 transducer \$1;
#X msg 165 41 transducer;
#X obj 30 220 s \$0-fsm;
#X msg 40 196 semiring;
#X msg 30 174 semiring \$1;
#X msg 29 125 boolean;
#X msg 90 125 log;
#X msg 122 126 real;
#X msg 160 125 trivial;
#X msg 218 125 tropical;
#X obj 30 153 symbol;
#X msg 286 125 OTHER;
#X connect 1 0 0 0;
#X connect 2 0 1 0;
#X connect 3 0 0 0;
#X connect 4 0 6 0;
#X connect 6 0 5 0;
#X connect 7 0 5 0;
#X connect 9 0 8 0;
#X connect 10 0 8 0;
#X connect 11 0 16 0;
#X connect 12 0 16 0;
#X connect 13 0 16 0;
#X connect 14 0 16 0;
#X connect 15 0 16 0;
#X connect 16 0 10 0;
#X connect 17 0 16 0;
#X restore 711 65 pd flags;
#X obj 600 8 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 361 336 concat a1;
#X floatatom 689 35 5 0 0 0 - - -;
#X obj 366 59 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 113 360 s \$0-fsm-out;
#X obj 741 16 pool;
#X msg 94 120 automaton fsm-help;
#X msg 105 220 load gfsm-help.tfst;
#N canvas 22 7 466 454 draw 0;
#X obj 361 16 zexy;
#X obj 26 15 r \$0-draw-s;
#X obj 68 68 f \$0;
#X obj 68 110 s \$0-fsm;
#X obj 68 47 t b;
#X obj 99 352 t b;
#X obj 98 418 shell;
#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 69 331 shell;
#X obj 125 215 r \$0-drawmode-s;
#X obj 67 238 demux 0 1;
#X obj 240 214 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X msg 68 89 draw_dot \$1draw.dot;
#X obj 67 136 r \$0-fsm-out;
#X obj 67 158 route draw_dot;
#X obj 67 180 symbol;
#X msg 48 295 dotgv.sh \$1;
#X msg 145 294 dotty \$1;
#X obj 67 203 t s s;
#X obj 98 372 symbol;
#X msg 98 395 rm -f \$1;
#X connect 1 0 4 0;
#X connect 2 0 12 0;
#X connect 4 0 2 0;
#X connect 5 0 19 0;
#X connect 7 0 4 0;
#X connect 8 1 5 0;
#X connect 9 0 10 1;
#X connect 10 0 16 0;
#X connect 10 1 17 0;
#X connect 11 0 10 1;
#X connect 12 0 3 0;
#X connect 13 0 14 0;
#X connect 14 0 15 0;
#X connect 15 0 18 0;
#X connect 16 0 8 0;
#X connect 17 0 8 0;
#X connect 18 0 10 0;
#X connect 18 1 19 1;
#X connect 19 0 20 0;
#X connect 20 0 6 0;
#X restore 16 251 pd draw;
#X msg 258 216 load_bin lkptest.gfst;
#X msg 261 238 load_bin lkpin.gfst;
#X obj 21 385 gfsm_automaton a1;
#X obj 22 404 gfsm_automaton a2;
#X msg 626 245 connect;
#X msg 739 352 clear;
#X connect 1 0 2 0;
#X connect 1 0 81 0;
#X connect 3 0 5 0;
#X connect 4 0 5 0;
#X connect 6 0 1 0;
#X connect 7 0 25 0;
#X connect 8 0 67 0;
#X connect 9 0 8 0;
#X connect 10 0 69 0;
#X connect 11 0 8 0;
#X connect 12 0 10 0;
#X connect 13 0 70 0;
#X connect 14 0 13 0;
#X connect 15 0 72 0;
#X connect 16 0 20 0;
#X connect 17 0 20 1;
#X connect 18 0 20 2;
#X connect 19 0 20 3;
#X connect 20 0 48 1;
#X connect 21 0 22 0;
#X connect 22 0 48 0;
#X connect 22 1 20 0;
#X connect 23 0 16 0;
#X connect 23 0 17 0;
#X connect 23 0 18 0;
#X connect 23 0 19 0;
#X connect 24 0 28 0;
#X connect 29 0 37 0;
#X connect 30 0 37 0;
#X connect 31 0 38 0;
#X connect 32 0 38 0;
#X connect 33 0 36 0;
#X connect 34 0 36 0;
#X connect 35 0 36 0;
#X connect 39 0 42 0;
#X connect 40 0 42 0;
#X connect 41 0 40 0;
#X connect 44 0 41 0;
#X connect 45 0 42 0;
#X connect 46 0 42 0;
#X connect 48 0 24 0;
#X connect 49 0 5 0;
#X connect 50 0 42 0;
#X connect 51 0 42 0;
#X connect 52 0 42 0;
#X connect 54 0 53 0;
#X connect 55 0 53 0;
#X connect 56 0 53 0;
#X connect 57 0 56 0;
#X connect 58 0 57 0;
#X connect 59 0 53 0;
#X connect 60 0 53 0;
#X connect 61 0 53 0;
#X connect 62 0 37 0;
#X connect 63 0 38 0;
#X connect 64 0 38 0;
#X connect 66 0 26 0;
#X connect 67 0 26 0;
#X connect 68 0 17 0;
#X connect 68 0 18 0;
#X connect 68 0 19 0;
#X connect 69 0 25 0;
#X connect 70 0 27 0;
#X connect 71 0 72 1;
#X connect 72 0 73 0;
#X connect 73 0 27 0;
#X connect 74 0 53 0;
#X connect 75 0 38 0;
#X connect 77 0 68 0;
#X connect 78 0 42 0;
#X connect 79 0 20 4;
#X connect 80 0 15 0;
#X connect 83 0 5 0;
#X connect 84 0 37 0;
#X connect 86 0 38 0;
#X connect 87 0 38 0;
#X connect 90 0 53 0;
#X connect 91 0 53 0;

--- NEW FILE: Makefile.am ---
# File: ./src/Makefile.am
# Package: pd-gfsm
# Description:
#   + src-level automake file
#
# Process this file with Automake to create Makefile.in.
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# Options & Subdirectories
#-----------------------------------------------------------------------

## --- recursion subdirectories
#SUBDIRS = 

## --- pseudo-deps for '.SUFFIXES'
SUFFIXES = . at PDEXT@

#-----------------------------------------------------------------------
# Flags and variables
#-----------------------------------------------------------------------
PDEXT    = @PDEXT@
EXEEXT   = . at PDEXT@

#-----------------------------------------------------------------------
# pd externals (hacked _PROGRAMS target)
#-----------------------------------------------------------------------

## --- externals
pdexterns_PROGRAMS = gfsm

## --- patches
pdexterns_DATA = \
	gfsm_markov.pd

## --- documentation
pddoc_DATA = \
	gfsm-help.pd \
	gfsm_alphabet-help.pd \
	gfsm_automaton-help.pd \
	gfsm_state-help.pd \
	gfsm_markov-help.pd

#-----------------------------------------------------------------------
# sources
#-----------------------------------------------------------------------

gfsm_SOURCES = \
	config.h \
	atom_alphabet.h atom_alphabet.c \
	pd_alphabet.h  pd_alphabet.c \
	\
	pd_automaton.h pd_automaton.c \
	pd_algebra.c \
	\
	pd_state.h pd_state.c \
	\
	pd_io.h pd_io.c \
	\
	pd_gfsm.h pd_gfsm.c


#----------------------------------------------------------------------
# external compilation : flags
#-----------------------------------------------------------------------
DEFS    = @DEFS@
AFLAGS  = @AFLAGS@
DFLAGS  = @DFLAGS@
IFLAGS  = @IFLAGS@
LFLAGS  = @LFLAGS@
OFLAGS  = @OFLAGS@
WFLAGS  = -Wall

AM_CPPFLAGS = $(IFLAGS) $(DFLAGS)
AM_CFLAGS   = $(OFLAGS) $(WFLAGS) $(AFLAGS)
AM_CXXFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)

gfsm_LDFLAGS = $(LFLAGS)
#gfsm_LDADD   =

#-----------------------------------------------------------------------
# additional hacks
#-----------------------------------------------------------------------
#(none)

#-----------------------------------------------------------------------
# Variables: cleanup
#-----------------------------------------------------------------------
## --- mostlyclean: built by 'make' & commonly rebuilt
#MOSTLYCLEANFILES =

## --- clean: built by 'make'
CLEANFILES = *$(EXEEXT)

## --- distclean: built by 'configure'
DISTCLEANFILES = \
	config.log	\
	config.cache	\
	config.status

## -- maintainerclean: built by maintainer / by hand
MAINTAINERCLEANFILES = *~ \
	$(PODS:.pod=.txt) \
	Makefile Makefile.in \
	aclocal.m4 \
	configure \
	install-sh \
	stamp-h.in \
	config.h.in

maintainer-clean-local:
	rm -rf autom4te.cache

#CVSCLEAN_SUBDIRS = $(SUBDIRS)

#CVSCLEANFILES = Makefile.in Makefile


#-----------------------------------------------------------------------
# Variables: distribution
#-----------------------------------------------------------------------

## --- extra distribution files
EXTRA_DIST = \
	$(pddoc_DATA) \
	$(pdexterns_DATA)


## --- recursion subdirectories for 'make dist'
DIST_SUBDIRS = $(SUBDIRS)

## --- dist-hook: when another 'Makefile.am' is overkill
#DISTHOOK_DIRS = foo
#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
#dist-hook:
#	for d in $(DISTHOOK_DIRS); do\
#	  mkdir -p $(distdir)/$$d ;\
#	done
#	for f in $(DISTHOOK_FILES); do\
#	  cp -p $(srcdir)/$$f $(distdir)/$$f ;\
#	done

#dist-bz2: dist-bzip2 ;


#-----------------------------------------------------------------------
# Rules: cleanup
#-----------------------------------------------------------------------
.PHONY: cvsclean cvsclean-hook

cvsclean: maintainer-clean ;


--- NEW FILE: test-alphabet.pd ---
#N canvas 0 0 450 300 10;
#X obj 366 21 fsm;
#X obj 130 127 fsm_alphabet;

--- NEW FILE: lkptest.tfst ---
0	0	1	2	1
0	0	2	3	1
0	0	3	1	1
0	1	2	2	1
0	0
1	2	2	2	1
2	3	3	3	1
3	0

--- NEW FILE: pd_io.h ---
/*=============================================================================*\
 * File: pd_io.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd; I/O
 *
 * Copyright (c) 2006 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

/*=====================================================================
 * Protos
 *=====================================================================*/
#ifndef PD_GFSM_IO_H
#define PD_GFSM_IO_H

/*----------------------------------------------------------------------
 * includes
 */
#include <m_pd.h>
#include <gfsm.h>

/*----------------------------------------------------------------------
 * I/O stuff
 */
gfsmIOHandle *pd_gfsm_console_handle_new(void);

void pd_gfsm_console_handle_free(gfsmIOHandle *ioh);

#endif /* PD_GFSM_IO_H */

--- NEW FILE: lkpin.tfst ---
0	1	2	2
1	2	2	2
2	3	3	3
3

--- NEW FILE: pd_io.c ---
/*=============================================================================*\
 * File: pd_io.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd: I/O
 *
 * Copyright (c) 2006 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_io.h>

/*=====================================================================
 * I/O utilities
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_console_handle_flush()
 */
static void pd_gfsm_console_handle_flush(gfsmPosGString *pgs)
{
  if (pgs->gs->len) post(pgs->gs->str);
  g_string_truncate(pgs->gs,0);
  pgs->pos = 0;
}

/*--------------------------------------------------------------------
 * pd_gfsm_console_handle_new()
 */
gfsmIOHandle *pd_gfsm_console_handle_new(void)
{
  GString *gs = g_string_new("");
  gfsmPosGString *pgs = g_new(gfsmPosGString,1);
  gfsmIOHandle *ioh;
  pgs->gs  = gs;
  pgs->pos = 0;

  ioh = gfsmio_new_gstring(pgs);
  ioh->flush_func = (gfsmIOFlushFunc)pd_gfsm_console_handle_flush;

  return ioh;
}

/*--------------------------------------------------------------------
 * pd_gfsm_console_handle_free()
 */
void pd_gfsm_console_handle_free(gfsmIOHandle *ioh)
{
  gfsmPosGString *pgs = (gfsmPosGString*)ioh->handle;
  gfsmio_flush(ioh);
  g_string_free(pgs->gs,TRUE);
  g_free(pgs);
  g_free(ioh);
}

--- NEW FILE: test-state2.pd ---
#N canvas 346 27 616 494 10;
#X obj 13 7 gfsm;
#X msg 23 84 automaton;
#X msg 21 43 automaton a1;
#X obj 51 6 zexy;
#X msg 22 62 automaton a2;
#X obj 30 285 r \$0-state;
#X obj 19 332 print STATE-1;
#X obj 136 76 s \$0-state;
#X msg 150 48 id;
#X msg 136 27 set \$1;
#X floatatom 153 9 5 0 0 0 - - -;
#X obj 19 308 gfsm_state a1;
#X obj 135 10 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 218 11 degree;
#X obj 218 74 s \$0-state;
#X msg 19 164 arc_first;
#X msg 23 188 arc_next;
#X obj 243 314 gfsm_automaton a1;
#X obj 243 180 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
-1;
#X obj 243 198 openpanel;
#X msg 243 264 load_bin \$1;
#X obj 243 335 print A1-1;
#X obj 254 293 r \$0-fsm;
#X obj 337 226 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
-1 -1;
#N canvas 0 0 466 454 draw 0;
#X obj 361 16 zexy;
#X obj 67 25 r \$0-draw-s;
#X obj 68 68 f \$0;
#X msg 176 74 save_bin \$1draw.gfst;
#X obj 176 98 s \$0-fsm;
#X obj 68 162 shell;
#X obj 68 47 t b;
#X obj 68 91 t f f;
#X msg 69 237 dotgv.sh \$1draw.dot;
#X obj 171 311 f \$0;
#X obj 172 291 t b;
#X obj 171 357 shell;
#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
#X obj 142 270 shell;
#X msg 220 236 dotty \$1draw.dot;
#X obj 169 183 r \$0-drawmode-s;
#X obj 111 206 demux 0 1;
#X obj 110 163 t b;
#X obj 111 184 f \$0;
#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X connect 1 0 6 0;
#X connect 2 0 7 0;
#X connect 3 0 4 0;
#X connect 5 1 19 0;
#X connect 6 0 2 0;
#X connect 7 0 13 0;
#X connect 7 1 3 0;
#X connect 8 0 15 0;
#X connect 9 0 14 0;
#X connect 10 0 9 0;
#X connect 12 0 6 0;
#X connect 13 0 5 0;
#X connect 14 0 11 0;
#X connect 15 1 10 0;
#X connect 16 0 15 0;
#X connect 17 0 18 1;
#X connect 18 0 8 0;
#X connect 18 1 16 0;
#X connect 19 0 20 0;
#X connect 20 0 18 0;
#X connect 21 0 18 1;
#X restore 338 250 pd draw;
#X obj 365 226 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271
-1 -1 0 1;
#X obj 243 242 symbol;
#X obj 115 141 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 486 0 310 377 weight_sum 1;
#X obj 34 11 inlet;
#X msg 34 104 arc_next;
#X obj 34 309 f 0;
#X obj 209 82 0;
#X obj 99 228 unpack 0 0 0 0;
#X obj 193 252 + 0;
#X obj 98 253 t f f;
#X obj 87 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 34 340 outlet;
#X obj 34 157 gfsm_state a1 0;
#X obj 70 136 r \$0-state;
#X obj 88 340 s \$0-wsum-out;
#X obj 113 13 r \$0-wsum-in;
#X obj 34 80 until;
#X obj 34 204 route bang;
#X obj 34 225 t b b;
#X obj 34 182 route arc_next;
#X obj 34 33 t b b b b;
#X msg 101 104 arc_reset;
#X connect 0 0 17 0;
#X connect 1 0 9 0;
#X connect 2 0 8 0;
#X connect 2 0 11 0;
#X connect 3 0 5 1;
#X connect 4 3 5 0;
#X connect 5 0 6 0;
#X connect 6 0 5 1;
#X connect 6 1 2 1;
#X connect 7 0 17 0;
#X connect 9 0 16 0;
#X connect 10 0 9 0;
#X connect 12 0 17 0;
#X connect 13 0 1 0;
#X connect 14 0 15 0;
#X connect 14 1 4 0;
#X connect 15 0 2 0;
#X connect 15 1 13 1;
#X connect 16 0 14 0;
#X connect 17 0 13 0;
#X connect 17 1 3 0;
#X connect 17 2 18 0;
#X connect 17 3 13 1;
#X connect 18 0 9 0;
#X restore 115 161 pd weight_sum;
#X obj 114 332 s \$0-state-out;
#X obj 114 224 print WSUM;
#X obj 252 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 298 9 405 465 rand_arc 0;
#X obj 40 9 inlet;
#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
;
#X msg 41 98 arc_next;
#X obj 136 266 unpack 0 0 0 0;
#X obj 41 415 outlet;
#X obj 41 163 gfsm_state a1 0;
#X obj 76 140 r \$0-state;
#X obj 243 97 s \$0-wsum-in;
#X obj 245 119 r \$0-wsum-out;
#X obj 245 166 random 131072;
#X obj 245 140 t b f;
#X obj 245 190 / 131072;
#X obj 245 214 * 1;
#X obj 229 334 moses 0;
#X obj 245 237 * -1;
#X obj 229 289 + 0;
#X obj 229 312 t f f;
#X obj 106 327 spigot;
#X obj 143 304 0;
#X obj 170 304 1;
#X obj 107 10 r \$0-randarc-in;
#X obj 92 415 s \$0-randarc-out;
#X obj 41 76 until;
#X obj 41 220 route bang;
#X obj 106 244 t l l;
#X obj 228 353 t b;
#X obj 272 353 t b;
#X obj 106 348 t l b;
#X obj 41 348 t b b;
#X obj 41 197 route arc_next;
#X msg 107 97 arc_reset;
#X obj 41 30 t b b b b;
#X connect 0 0 31 0;
#X connect 1 0 31 0;
#X connect 2 0 5 0;
#X connect 3 3 15 0;
#X connect 5 0 29 0;
#X connect 6 0 5 0;
#X connect 8 0 10 0;
#X connect 9 0 11 0;
#X connect 10 0 9 0;
#X connect 10 1 12 1;
#X connect 11 0 12 0;
#X connect 12 0 14 0;
#X connect 13 0 25 0;
#X connect 13 1 26 0;
#X connect 14 0 15 1;
#X connect 15 0 16 0;
#X connect 16 0 13 0;
#X connect 16 1 15 1;
#X connect 17 0 27 0;
#X connect 18 0 17 1;
#X connect 19 0 17 1;
#X connect 20 0 31 0;
#X connect 22 0 2 0;
#X connect 23 0 28 0;
#X connect 23 1 24 0;
#X connect 24 0 17 0;
#X connect 24 1 3 0;
#X connect 25 0 18 0;
#X connect 26 0 19 0;
#X connect 27 0 21 0;
#X connect 27 0 4 0;
#X connect 27 1 22 1;
#X connect 28 0 4 0;
#X connect 28 0 21 0;
#X connect 28 1 22 1;
#X connect 29 0 23 0;
#X connect 30 0 5 0;
#X connect 31 0 22 0;
#X connect 31 1 30 0;
#X connect 31 2 7 0;
#X connect 31 3 22 1;
#X restore 252 116 pd rand_arc;
#X obj 395 113 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 102 2 392 492 rand_incr 0;
#X obj 40 9 inlet;
#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
;
#X obj 41 54 s \$0-randarc-in;
#X obj 43 76 r \$0-randarc-out;
#X obj 42 98 route bang;
#X obj 41 30 t b;
#X obj 42 177 gfsm_automaton a1;
#X obj 209 157 unpack 0 0 0 0;
#X obj 55 154 r \$0-automaton;
#X msg 42 131 root;
#X obj 42 199 route root;
#X obj 42 221 route bang;
#X obj 107 336 outlet;
#X obj 211 337 outlet;
#X obj 271 335 outlet;
#X msg 8 247 root 0;
#X obj 107 254 t f f;
#X obj 137 295 s \$0-state;
#X msg 137 274 set \$1;
#X obj 326 336 outlet;
#X connect 0 0 5 0;
#X connect 1 0 5 0;
#X connect 3 0 4 0;
#X connect 4 0 9 0;
#X connect 4 1 7 0;
#X connect 5 0 2 0;
#X connect 6 0 10 0;
#X connect 7 0 16 0;
#X connect 7 1 13 0;
#X connect 7 2 14 0;
#X connect 7 3 19 0;
#X connect 8 0 6 0;
#X connect 9 0 6 0;
#X connect 10 0 11 0;
#X connect 11 0 15 0;
#X connect 11 1 16 0;
#X connect 15 0 6 0;
#X connect 16 0 12 0;
#X connect 16 1 18 0;
#X connect 18 0 17 0;
#X restore 395 132 pd rand_incr;
#X obj 254 157 print RAND_ARC;
#X obj 336 33 s \$0-state;
#X obj 326 54 s \$0-fsm;
#X obj 13 105 s \$0-automaton;
#X obj 326 12 r \$0-automaton;
#X obj 13 214 s \$0-state-a;
#X obj 19 262 r \$0-state-a;
#X obj 195 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 230 140 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 470 10 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X floatatom 493 10 5 0 0 0 - - -;
#X obj 471 30 metro 1000;
#X obj 417 300 gfsm_alphabet alph1;
#X obj 518 214 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
-1;
#X obj 518 232 openpanel;
#X obj 518 254 symbol;
#X msg 518 275 load \$1;
#X obj 481 375 print RI-ATOM;
#X msg 419 273 char2atom \$1;
#X floatatom 436 245 5 0 0 0 - - -;
#X obj 482 332 fromsymbol;
#N canvas 0 0 450 300 ri_print 0;
#X obj 48 22 inlet;
#X obj 101 22 inlet;
#X obj 155 22 inlet;
#X obj 206 22 inlet;
#X obj 319 22 inlet;
#X obj 93 97 spigot;
#X obj 93 57 pack 0 0 0 0;
#X obj 93 122 unpack 0 0 0 0;
#X obj 124 196 print RI-LO;
#X obj 186 155 print RI-WT;
#X obj 155 175 print RI-HI;
#X obj 93 215 print RI-NXT;
#X connect 0 0 6 0;
#X connect 1 0 6 1;
#X connect 2 0 6 2;
#X connect 3 0 6 3;
#X connect 4 0 5 1;
#X connect 5 0 7 0;
#X connect 6 0 5 0;
#X connect 7 0 11 0;
#X connect 7 1 8 0;
#X connect 7 2 10 0;
#X connect 7 3 9 0;
#X restore 420 160 pd ri_print;
#X obj 488 131 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 114 181 spigot;
#X obj 162 181 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 253 138 spigot;
#X obj 301 138 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 29 410 grattsdict;
#X obj 470 51 t b b;
#X obj 475 100 spigot;
#X msg 506 80 0;
#X msg 534 80 1;
#X obj 548 456 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 0 0 450 300 load_dict 0;
#X obj 31 16 inlet;
#X obj 31 38 t b;
#X msg 31 67 load /home/moocow/src/pd/externs/ratts/dict/beep-b.txt
cr;
#X obj 33 108 outlet;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X restore 30 391 pd load_dict;
#X obj 31 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 243 365 gpratts~ 10 \$0p /gpratts;
#X obj 30 432 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X msg 30 453 \; pd dsp \$1;
#X obj 434 74 bng 15 250 20 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 435 103 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 424 202 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 367 340 route 0;
#X msg 202 284 info;
#X msg 13 141 arc_reset;
#X msg 250 219 markov.gfst;
#X msg 538 211 markov.lab;
#X floatatom 114 204 8 0 0 0 - - -;
#X obj 481 355 spigot;
#X obj 533 354 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 145 359 ms8a~ p gpr;
#X connect 1 0 38 0;
#X connect 2 0 38 0;
#X connect 4 0 38 0;
#X connect 5 0 11 0;
#X connect 8 0 7 0;
#X connect 9 0 7 0;
#X connect 10 0 9 0;
#X connect 11 0 6 0;
#X connect 11 0 29 0;
#X connect 12 0 10 0;
#X connect 13 0 14 0;
#X connect 15 0 40 0;
#X connect 16 0 40 0;
#X connect 17 0 21 0;
#X connect 18 0 19 0;
#X connect 19 0 26 0;
#X connect 20 0 17 0;
#X connect 22 0 17 0;
#X connect 26 0 20 0;
#X connect 27 0 28 0;
#X connect 31 0 32 0;
#X connect 32 0 60 0;
#X connect 33 0 34 0;
#X connect 34 0 56 0;
#X connect 34 0 53 0;
#X connect 34 1 56 1;
#X connect 34 2 56 2;
#X connect 34 3 56 3;
#X connect 39 0 37 0;
#X connect 39 0 36 0;
#X connect 41 0 11 0;
#X connect 44 0 46 0;
#X connect 45 0 46 1;
#X connect 46 0 63 0;
#X connect 47 1 55 0;
#X connect 48 0 49 0;
#X connect 49 0 50 0;
#X connect 50 0 51 0;
#X connect 51 0 47 0;
#X connect 53 0 47 0;
#X connect 54 0 53 0;
#X connect 55 0 76 0;
#X connect 55 0 82 0;
#X connect 57 0 56 4;
#X connect 58 0 81 0;
#X connect 59 0 58 1;
#X connect 60 0 35 0;
#X connect 61 0 60 1;
#X connect 63 0 65 0;
#X connect 63 1 64 0;
#X connect 64 0 34 0;
#X connect 65 0 64 1;
#X connect 66 0 64 1;
#X connect 68 0 62 0;
#X connect 69 0 68 0;
#X connect 70 0 84 0;
#X connect 70 0 84 1;
#X connect 70 1 66 0;
#X connect 71 0 72 0;
#X connect 76 1 70 0;
#X connect 77 0 17 0;
#X connect 78 0 40 0;
#X connect 79 0 26 0;
#X connect 80 0 50 0;
#X connect 81 0 30 0;
#X connect 82 0 52 0;
#X connect 83 0 82 1;

--- NEW FILE: gfsm-help.pd ---
#N canvas 0 0 430 269 10;
#X obj 66 7 gfsm;
#X text 126 232 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X text 21 43 EXTERNALS:;
#X obj 41 72 gfsm_alphabet;
#X obj 41 98 gfsm_automaton;
#X text 159 71 integer <-> atom mapping;
#X obj 41 124 gfsm_state;
#X text 161 125 automaton position;
#X text 160 98 weighted finite state machine;
#X text 21 184 SEE ALSO:;
#X text 38 201 gfsmutils(1);
#X text 99 8 : finite state machine external library;
#X obj 40 150 gfsm_markov;
#X text 161 151 trainable Markov chain;

--- NEW FILE: test-markov.pd ---
#N canvas 79 27 832 322 10;
#X obj 21 23 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
-1 -1;
#N canvas 0 0 466 454 draw 0;
#X obj 361 16 zexy;
#X obj 67 25 r \$0-draw-s;
#X obj 68 68 f \$0;
#X obj 67 177 shell;
#X obj 68 47 t b;
#X obj 68 91 t f f;
#X msg 68 252 dotgv.sh \$1draw.dot;
#X obj 170 326 f \$0;
#X obj 171 306 t b;
#X obj 170 372 shell;
#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 170 349 rm -f \$1draw.gfst \$1draw.dot;
#X obj 141 285 shell;
#X msg 219 251 dotty \$1draw.dot;
#X obj 168 198 r \$0-drawmode-s;
#X obj 110 221 demux 0 1;
#X obj 109 178 t b;
#X obj 110 199 f \$0;
#X obj 283 197 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 176 98 s \$0-markov;
#X msg 176 74 save_bin \$1draw;
#X msg 68 137 gfsmdraw -i \$1draw.lab -o \$1draw.lab \$1draw.gfst -F
\$1draw.dot;
#X connect 1 0 4 0;
#X connect 2 0 5 0;
#X connect 3 1 16 0;
#X connect 4 0 2 0;
#X connect 5 0 21 0;
#X connect 5 1 20 0;
#X connect 6 0 12 0;
#X connect 7 0 11 0;
#X connect 8 0 7 0;
#X connect 10 0 4 0;
#X connect 11 0 9 0;
#X connect 12 1 8 0;
#X connect 13 0 12 0;
#X connect 14 0 15 1;
#X connect 15 0 6 0;
#X connect 15 1 13 0;
#X connect 16 0 17 0;
#X connect 17 0 15 0;
#X connect 18 0 15 1;
#X connect 20 0 19 0;
#X connect 21 0 3 0;
#X restore 22 47 pd draw;
#X obj 34 203 r \$0-markov;
#X obj 104 6 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
-1;
#X obj 104 24 openpanel;
#X msg 104 90 load_bin \$1;
#X obj 104 68 symbol;
#X msg 111 45 markov;
#X obj 103 110 s \$0-markov;
#X obj 204 6 bng 15 250 50 0 empty empty empty 0 -6 0 8 -228992 -1
-1;
#X obj 204 68 symbol;
#X obj 203 110 s \$0-markov;
#X obj 204 24 savepanel;
#X msg 204 90 save_bin \$1;
#X msg 211 45 markov2;
#X obj 49 22 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
-1 0 1;
#X msg 336 8 fsm info;
#X msg 342 28 clear;
#X obj 336 75 s \$0-markov;
#X msg 339 151 next;
#X obj 339 172 s \$0-markov;
#X obj 339 108 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 339 127 metro 500;
#X obj 302 153 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X floatatom 364 107 6 0 0 0 - - -;
#X msg 382 255 add1 \$1;
#X floatatom 341 207 5 0 0 0 - - -;
#X msg 382 208 foo;
#X msg 413 208 bar;
#X msg 442 209 baz;
#X obj 382 279 s \$0-markov;
#X obj 34 225 gfsm_markov markov;
#X obj 384 234 symbol;
#X floatatom 481 210 5 0 0 0 - - -;
#X msg 522 211 foo;
#X msg 553 211 bar;
#X msg 582 212 baz;
#X obj 522 282 s \$0-markov;
#X obj 524 237 symbol;
#X msg 521 258 addi1 \$1;
#X msg 349 51 set;
#X floatatom 538 57 5 0 0 0 - - -;
#X msg 480 138 add1 \$1;
#X floatatom 480 119 5 0 0 0 - - -;
#X obj 539 170 s \$0-markov;
#X floatatom 513 11 5 0 0 0 - - -;
#X obj 480 29 metro 100;
#X obj 480 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X obj 480 98 + 1;
#X floatatom 649 59 5 0 0 0 - - -;
#X floatatom 591 121 5 0 0 0 - - -;
#X floatatom 624 13 5 0 0 0 - - -;
#X obj 591 31 metro 100;
#X obj 591 13 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X obj 591 100 + 1;
#X msg 591 140 addi1 \$1;
#X obj 480 77 random 16;
#X obj 591 79 random 16;
#X obj 34 260 spigot;
#X obj 83 262 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X obj 687 207 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 687 227 metro 2000;
#X floatatom 715 208 5 0 0 0 - - -;
#X msg 689 247 set;
#X obj 689 267 s \$0-markov;
#X obj 667 227 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X floatatom 692 117 5 0 0 0 - - -;
#X msg 692 137 addi \$1 42 5;
#X obj 32 284 print MARKOV-LO;
#X obj 155 284 print MARKOV-HI;
#X obj 175 241 print MARKOV-X;
#X obj 152 262 spigot;
#X obj 201 264 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X floatatom 706 52 5 0 0 0 - - -;
#X msg 705 70 add \$1 24 5;
#X msg 138 192 set 0 \, next;
#X obj 176 219 spigot;
#X obj 224 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X msg 162 45 big;
#X msg 270 44 big2;
#X msg 49 73 markov2;
#X connect 2 0 31 0;
#X connect 3 0 4 0;
#X connect 4 0 6 0;
#X connect 5 0 8 0;
#X connect 6 0 5 0;
#X connect 7 0 6 0;
#X connect 9 0 12 0;
#X connect 10 0 13 0;
#X connect 12 0 10 0;
#X connect 13 0 11 0;
#X connect 14 0 10 0;
#X connect 16 0 18 0;
#X connect 17 0 18 0;
#X connect 19 0 20 0;
#X connect 21 0 22 0;
#X connect 22 0 19 0;
#X connect 24 0 22 1;
#X connect 25 0 30 0;
#X connect 26 0 25 0;
#X connect 27 0 32 0;
#X connect 28 0 32 0;
#X connect 29 0 32 0;
#X connect 31 0 58 0;
#X connect 31 1 71 0;
#X connect 31 2 75 0;
#X connect 31 2 76 0;
#X connect 32 0 25 0;
#X connect 33 0 39 0;
#X connect 34 0 38 0;
#X connect 35 0 38 0;
#X connect 36 0 38 0;
#X connect 38 0 39 0;
#X connect 39 0 37 0;
#X connect 40 0 18 0;
#X connect 41 0 56 1;
#X connect 42 0 44 0;
#X connect 43 0 42 0;
#X connect 45 0 46 1;
#X connect 46 0 56 0;
#X connect 47 0 46 0;
#X connect 48 0 43 0;
#X connect 49 0 57 1;
#X connect 50 0 55 0;
#X connect 51 0 52 1;
#X connect 52 0 57 0;
#X connect 53 0 52 0;
#X connect 54 0 50 0;
#X connect 55 0 44 0;
#X connect 56 0 48 0;
#X connect 57 0 54 0;
#X connect 58 0 68 0;
#X connect 59 0 58 1;
#X connect 60 0 61 0;
#X connect 61 0 63 0;
#X connect 61 0 65 0;
#X connect 62 0 61 1;
#X connect 63 0 64 0;
#X connect 66 0 67 0;
#X connect 67 0 44 0;
#X connect 71 0 69 0;
#X connect 72 0 71 1;
#X connect 73 0 74 0;
#X connect 74 0 44 0;
#X connect 75 0 31 0;
#X connect 76 0 70 0;
#X connect 77 0 76 1;
#X connect 78 0 6 0;
#X connect 79 0 10 0;
#X connect 80 0 6 0;

--- NEW FILE: gfsm_markov-help.pd ---
#N canvas 39 25 680 536 10;
#X text 150 -2 gfsm_markov : Markov chain using gfsm;
#X text 15 41 INLETS:;
#X text 28 56 1 - control messages;
#X text 233 41 OUTLETS:;
#X text 17 21 SYNTAX: gfsm_markov OBJNAME;
#X text 365 24 REQUIRES:;
#X obj 433 24 gfsm;
#X obj 469 24 zexy;
#X text 246 83 3 - bang when stuck;
#X text 247 69 2 - upper side atoms on "next";
#X text 247 55 1 - lower side atoms on "next";
#X obj 39 494 print lo;
#X obj 134 494 print hi;
#X obj 230 494 print stuck;
#X obj 39 473 gfsm_markov help-gfsm-markov;
#X msg 48 175 load_bin help-gfsm_markov;
#X msg 49 192 save-bin help-gfsm_markov;
#X msg 39 125 load help-gfsm_markov;
#X msg 40 142 save help-gfsm_markov;
#X msg 55 250 set foo;
#X msg 61 267 set;
#X msg 60 298 add foo bar 0.42;
#X msg 65 361 addi foo baz 1;
#X msg 78 408 next \$1;
#X floatatom 78 392 5 0 0 0 - - -;
#X msg 78 428 next;
#X msg 78 450 bang;
#X msg 53 223 clear;
#X text 273 126 load BASE : load text files BASE.lab and BASE.tfst
;
#X text 274 142 save BASE : save text files BASE.lab \, BASE.tfst;
#X text 246 175 load_bin BASE : load files BASE.lab \, BASE.gfst;
#X text 246 192 save_bin BASE : save files BASE.lab \, BASE.gfst;
#X text 302 224 clear : clear underlying objects;
#X text 281 250 set ATOM : set current state to ATOM;
#X text 316 268 set : reset to initial (root) state;
#X text 227 297 add A1 A2 WEIGHT : add WEIGHT to arc on atom-pair A1:A2
;
#X text 276 316 add A1 A2 : like "add A1 A2 1";
#X msg 62 315 add foo baz;
#X text 297 332 add A1 : like "add A1 0 1";
#X text 219 361 addi A1 A2 WEIGHT : add WEIGHT to initial arc on A1:A2
;
#X text 273 408 next PROB : follow next arc with PROB hint-probability
;
#X text 308 429 next : follow next arc \, random probability;
#X text 308 450 bang : alias for "next";
#X text 375 516 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X msg 65 332 add foo;
#X connect 14 0 11 0;
#X connect 14 1 12 0;
#X connect 14 2 13 0;
#X connect 15 0 14 0;
#X connect 16 0 14 0;
#X connect 17 0 14 0;
#X connect 18 0 14 0;
#X connect 19 0 14 0;
#X connect 20 0 14 0;
#X connect 21 0 14 0;
#X connect 22 0 14 0;
#X connect 23 0 14 0;
#X connect 24 0 23 0;
#X connect 25 0 14 0;
#X connect 26 0 14 0;
#X connect 27 0 14 0;
#X connect 37 0 14 0;
#X connect 44 0 14 0;

--- NEW FILE: test.tfst ---
0	1	1	1	0
1	2	2	2	0
2

--- NEW FILE: test2.tfst ---
0	1	3	30	0
0	2	4	40	0
1	0
2	0

--- NEW FILE: test.lab ---
<epsilon>	0
a	1
b	2
c	3
foo	42

--- NEW FILE: test-alphabet2.pd ---
#N canvas 484 16 460 391 10;
#X obj 33 324 print LEFT;
#X obj 112 324 print RIGHT;
#X msg 24 13 alphabet foo;
#X msg 30 37 alphabet;
#X msg 132 7 insert x;
#X msg 136 29 insert life 42;
#X msg 201 79 atom2char x;
#X msg 218 135 char2atom 42;
#X msg 262 246 clear;
#X msg 204 100 a2c life;
#X msg 219 154 c2a 1;
#X msg 262 274 print;
#X floatatom 316 171 8 0 0 0 - - -;
#X msg 317 191 insert z \$1;
#X msg 405 190 c2a \$1;
#X floatatom 408 171 5 0 0 0 - - -;
#X msg 325 95 a2c \$1;
#X msg 321 42 x;
#X msg 349 42 life;
#X msg 385 41 z;
#X obj 324 73 symbol;
#X obj 33 302 gfsm_alphabet foo;
#X connect 2 0 21 0;
#X connect 3 0 21 0;
#X connect 4 0 21 0;
#X connect 5 0 21 0;
#X connect 6 0 21 0;
#X connect 7 0 21 0;
#X connect 8 0 21 0;
#X connect 9 0 21 0;
#X connect 10 0 21 0;
#X connect 11 0 21 0;
#X connect 12 0 13 0;
#X connect 13 0 21 0;
#X connect 14 0 21 0;
#X connect 15 0 14 0;
#X connect 16 0 21 0;
#X connect 17 0 20 0;
#X connect 18 0 20 0;
#X connect 19 0 20 0;
#X connect 20 0 16 0;
#X connect 21 0 0 0;
#X connect 21 1 1 0;

--- NEW FILE: test-state.pd ---
#N canvas 430 0 616 494 10;
#X obj 13 7 gfsm;
#X msg 23 84 automaton;
#X msg 21 43 automaton a1;
#X obj 51 6 zexy;
#X msg 22 62 automaton a2;
#X obj 30 285 r \$0-state;
#X obj 19 332 print STATE-1;
#X obj 136 76 s \$0-state;
#X msg 150 48 id;
#X msg 136 27 set \$1;
#X floatatom 153 9 5 0 0 0 - - -;
#X obj 19 308 gfsm_state a1;
#X obj 135 10 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 218 11 degree;
#X obj 218 74 s \$0-state;
#X msg 25 147 arc_first;
#X msg 29 171 arc_next;
#X obj 243 314 gfsm_automaton a1;
#X obj 243 180 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
-1;
#X obj 243 198 openpanel;
#X msg 243 264 load_bin \$1;
#X obj 243 335 print A1-1;
#X obj 254 293 r \$0-fsm;
#X obj 337 226 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
-1 -1;
#N canvas 0 0 466 454 draw 0;
#X obj 361 16 zexy;
#X obj 67 25 r \$0-draw-s;
#X obj 68 68 f \$0;
#X msg 176 74 save_bin \$1draw.gfst;
#X obj 176 98 s \$0-fsm;
#X obj 68 162 shell;
#X obj 68 47 t b;
#X obj 68 91 t f f;
#X msg 69 237 dotgv.sh \$1draw.dot;
#X obj 171 311 f \$0;
#X obj 172 291 t b;
#X obj 171 357 shell;
#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
#X obj 142 270 shell;
#X msg 220 236 dotty \$1draw.dot;
#X obj 169 183 r \$0-drawmode-s;
#X obj 111 206 demux 0 1;
#X obj 110 163 t b;
#X obj 111 184 f \$0;
#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X connect 1 0 6 0;
#X connect 2 0 7 0;
#X connect 3 0 4 0;
#X connect 5 1 19 0;
#X connect 6 0 2 0;
#X connect 7 0 13 0;
#X connect 7 1 3 0;
#X connect 8 0 15 0;
#X connect 9 0 14 0;
#X connect 10 0 9 0;
#X connect 12 0 6 0;
#X connect 13 0 5 0;
#X connect 14 0 11 0;
#X connect 15 1 10 0;
#X connect 16 0 15 0;
#X connect 17 0 18 1;
#X connect 18 0 8 0;
#X connect 18 1 16 0;
#X connect 19 0 20 0;
#X connect 20 0 18 0;
#X connect 21 0 18 1;
#X restore 338 250 pd draw;
#X obj 365 226 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271
-1 -1 0 1;
#X msg 250 219 test3.gfst;
#X obj 243 242 symbol;
#X obj 115 141 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 38 17 452 375 weight_sum 0;
#X obj 34 11 inlet;
#X msg 34 61 arc_first;
#X msg 46 88 arc_next;
#X obj 34 292 f 0;
#X obj 238 59 0;
#X obj 34 177 route arc_first arc_next;
#X obj 34 203 route bang;
#X obj 99 222 t b l;
#X obj 129 244 unpack 0 0 0 0;
#X obj 222 268 + 0;
#X obj 178 267 t f f;
#X obj 87 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 34 323 outlet;
#X obj 34 224 t b;
#X obj 34 143 gfsm_state a1 0;
#X obj 45 119 r \$0-state;
#X obj 88 323 s \$0-wsum-out;
#X obj 113 13 r \$0-wsum-in;
#X obj 71 250 delay 1;
#X obj 34 33 t b b b;
#X msg 290 56 stop;
#X floatatom 240 293 5 0 0 0 - - -;
#X obj 322 168 until;
#X connect 0 0 19 0;
#X connect 1 0 14 0;
#X connect 2 0 14 0;
#X connect 3 0 12 0;
#X connect 3 0 16 0;
#X connect 4 0 9 1;
#X connect 5 0 6 0;
#X connect 5 1 6 0;
#X connect 6 0 13 0;
#X connect 6 1 7 0;
#X connect 7 0 18 0;
#X connect 7 1 8 0;
#X connect 8 3 9 0;
#X connect 9 0 10 0;
#X connect 9 0 21 0;
#X connect 10 0 9 1;
#X connect 10 1 3 1;
#X connect 11 0 19 0;
#X connect 13 0 3 0;
#X connect 14 0 5 0;
#X connect 15 0 14 0;
#X connect 17 0 19 0;
#X connect 18 0 2 0;
#X connect 19 0 1 0;
#X connect 19 1 4 0;
#X connect 19 2 20 0;
#X connect 20 0 18 0;
#X restore 115 161 pd weight_sum;
#X obj 114 332 s \$0-state-out;
#X floatatom 114 182 8 0 0 0 - - -;
#X obj 114 224 print WSUM;
#X obj 252 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 302 0 392 492 rand_arc 0;
#X obj 40 9 inlet;
#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
;
#X msg 41 56 arc_first;
#X msg 56 93 arc_next;
#X obj 41 177 route arc_first arc_next;
#X obj 41 203 route bang;
#X obj 150 244 unpack 0 0 0 0;
#X obj 41 451 outlet;
#X obj 41 143 gfsm_state a1 0;
#X obj 77 122 r \$0-state;
#X obj 257 73 s \$0-wsum-in;
#X obj 259 95 r \$0-wsum-out;
#X obj 259 142 random 131072;
#X obj 259 116 t b f;
#X obj 259 166 / 131072;
#X obj 259 190 * 1;
#X obj 41 224 t b;
#X obj 243 316 moses 0;
#X obj 259 213 * -1;
#X obj 243 271 + 0;
#X obj 243 294 t f f;
#X obj 242 335 t b b;
#X obj 128 403 spigot;
#X obj 165 381 0;
#X obj 192 381 1;
#X obj 106 306 spigot;
#X obj 106 222 t b l l;
#X obj 286 335 t b b;
#X obj 169 284 0;
#X obj 143 284 1;
#X obj 107 10 r \$0-randarc-in;
#X obj 92 451 s \$0-randarc-out;
#X obj 81 326 delay 1;
#X obj 41 30 t b b b;
#X msg 177 127 stop;
#X connect 0 0 33 0;
#X connect 1 0 33 0;
#X connect 2 0 8 0;
#X connect 3 0 8 0;
#X connect 4 0 5 0;
#X connect 4 1 5 0;
#X connect 5 0 16 0;
#X connect 5 1 26 0;
#X connect 6 3 19 0;
#X connect 8 0 4 0;
#X connect 9 0 8 0;
#X connect 11 0 13 0;
#X connect 12 0 14 0;
#X connect 13 0 12 0;
#X connect 13 1 15 1;
#X connect 14 0 15 0;
#X connect 15 0 18 0;
#X connect 16 0 7 0;
#X connect 16 0 31 0;
#X connect 17 0 21 0;
#X connect 17 1 27 0;
#X connect 18 0 19 1;
#X connect 19 0 20 0;
#X connect 20 0 17 0;
#X connect 20 1 19 1;
#X connect 21 0 29 0;
#X connect 21 1 23 0;
#X connect 22 0 7 0;
#X connect 22 0 31 0;
#X connect 23 0 22 1;
#X connect 24 0 22 1;
#X connect 25 0 32 0;
#X connect 26 0 25 0;
#X connect 26 1 22 0;
#X connect 26 2 6 0;
#X connect 27 0 24 0;
#X connect 27 1 28 0;
#X connect 28 0 25 1;
#X connect 29 0 25 1;
#X connect 30 0 33 0;
#X connect 32 0 3 0;
#X connect 33 0 2 0;
#X connect 33 1 10 0;
#X connect 33 2 34 0;
#X connect 34 0 32 0;
#X restore 252 116 pd rand_arc;
#X obj 395 113 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 102 2 392 492 rand_incr 0;
#X obj 40 9 inlet;
#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
;
#X obj 41 54 s \$0-randarc-in;
#X obj 43 76 r \$0-randarc-out;
#X obj 42 98 route bang;
#X obj 41 30 t b;
#X obj 42 177 gfsm_automaton a1;
#X obj 209 157 unpack 0 0 0 0;
#X obj 55 154 r \$0-automaton;
#X msg 42 131 root;
#X obj 42 199 route root;
#X obj 42 221 route bang;
#X obj 107 336 outlet;
#X obj 211 337 outlet;
#X obj 271 335 outlet;
#X msg 8 247 root 0;
#X obj 107 254 t f f;
#X obj 137 295 s \$0-state;
#X msg 137 274 set \$1;
#X obj 326 336 outlet;
#X connect 0 0 5 0;
#X connect 1 0 5 0;
#X connect 3 0 4 0;
#X connect 4 0 9 0;
#X connect 4 1 7 0;
#X connect 5 0 2 0;
#X connect 6 0 10 0;
#X connect 7 0 16 0;
#X connect 7 1 13 0;
#X connect 7 2 14 0;
#X connect 7 3 19 0;
#X connect 8 0 6 0;
#X connect 9 0 6 0;
#X connect 10 0 11 0;
#X connect 11 0 15 0;
#X connect 11 1 16 0;
#X connect 15 0 6 0;
#X connect 16 0 12 0;
#X connect 16 1 18 0;
#X connect 18 0 17 0;
#X restore 395 132 pd rand_incr;
#X obj 254 157 print RAND_ARC;
#X obj 336 33 s \$0-state;
#X obj 326 54 s \$0-fsm;
#X obj 13 105 s \$0-automaton;
#X obj 326 12 r \$0-automaton;
#X obj 21 197 s \$0-state-a;
#X obj 19 262 r \$0-state-a;
#X obj 195 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 230 140 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 470 10 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
;
#X floatatom 493 10 5 0 0 0 - - -;
#X obj 471 30 metro 1000;
#X obj 417 300 gfsm_alphabet alph1;
#X obj 518 214 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
-1;
#X obj 518 232 openpanel;
#X obj 518 254 symbol;
#X msg 518 275 load \$1;
#X obj 452 342 print RI-ATOM;
#X msg 419 273 char2atom \$1;
#X floatatom 436 245 5 0 0 0 - - -;
#X obj 452 321 fromsymbol;
#N canvas 0 0 450 300 ri_print 0;
#X obj 48 22 inlet;
#X obj 101 22 inlet;
#X obj 155 22 inlet;
#X obj 206 22 inlet;
#X obj 319 22 inlet;
#X obj 93 97 spigot;
#X obj 93 57 pack 0 0 0 0;
#X obj 93 122 unpack 0 0 0 0;
#X obj 124 196 print RI-LO;
#X obj 186 155 print RI-WT;
#X obj 155 175 print RI-HI;
#X obj 93 215 print RI-NXT;
#X connect 0 0 6 0;
#X connect 1 0 6 1;
#X connect 2 0 6 2;
#X connect 3 0 6 3;
#X connect 4 0 5 1;
#X connect 5 0 7 0;
#X connect 6 0 5 0;
#X connect 7 0 11 0;
#X connect 7 1 8 0;
#X connect 7 2 10 0;
#X connect 7 3 9 0;
#X restore 420 160 pd ri_print;
#X obj 488 131 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 114 203 spigot;
#X obj 162 203 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 253 138 spigot;
#X obj 301 138 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 29 410 grattsdict;
#X obj 247 417 gvol~;
#X obj 246 454 dac~;
#X obj 470 51 t b b;
#X obj 475 100 spigot;
#X msg 506 80 0;
#X msg 534 80 1;
#X obj 548 456 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 0 0 450 300 load_dict 0;
#X obj 31 16 inlet;
#X obj 31 38 t b;
#X msg 31 67 load /home/moocow/src/pd/externs/ratts/dict/beep-b.txt
cr;
#X obj 33 108 outlet;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X restore 30 391 pd load_dict;
#X obj 31 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 366 367 gpratts~ 10 \$0p /gpratts;
#X obj 171 396 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X msg 171 417 \; pd dsp \$1;
#X obj 434 74 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 435 103 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 424 202 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 367 340 route 0;
#X connect 1 0 40 0;
#X connect 2 0 40 0;
#X connect 4 0 40 0;
#X connect 5 0 11 0;
#X connect 8 0 7 0;
#X connect 9 0 7 0;
#X connect 10 0 9 0;
#X connect 11 0 6 0;
#X connect 11 0 30 0;
#X connect 12 0 10 0;
#X connect 13 0 14 0;
#X connect 15 0 42 0;
#X connect 16 0 42 0;
#X connect 17 0 21 0;
#X connect 18 0 19 0;
#X connect 19 0 27 0;
#X connect 20 0 17 0;
#X connect 22 0 17 0;
#X connect 26 0 27 0;
#X connect 27 0 20 0;
#X connect 28 0 29 0;
#X connect 29 0 31 0;
#X connect 29 0 44 0;
#X connect 31 0 60 0;
#X connect 33 0 34 0;
#X connect 34 0 45 0;
#X connect 34 0 62 0;
#X connect 35 0 36 0;
#X connect 36 0 58 0;
#X connect 36 0 55 0;
#X connect 36 0 79 0;
#X connect 36 1 58 1;
#X connect 36 2 58 2;
#X connect 36 3 58 3;
#X connect 41 0 39 0;
#X connect 41 0 38 0;
#X connect 43 0 11 0;
#X connect 46 0 48 0;
#X connect 47 0 48 1;
#X connect 48 0 67 0;
#X connect 49 1 57 0;
#X connect 50 0 51 0;
#X connect 51 0 52 0;
#X connect 52 0 53 0;
#X connect 53 0 49 0;
#X connect 55 0 49 0;
#X connect 56 0 55 0;
#X connect 57 0 54 0;
#X connect 57 0 80 0;
#X connect 59 0 58 4;
#X connect 60 0 32 0;
#X connect 61 0 60 1;
#X connect 62 0 37 0;
#X connect 63 0 62 1;
#X connect 65 0 66 0;
#X connect 65 0 66 1;
#X connect 67 0 69 0;
#X connect 67 0 77 0;
#X connect 67 1 68 0;
#X connect 68 0 36 0;
#X connect 68 0 78 0;
#X connect 69 0 68 1;
#X connect 70 0 68 1;
#X connect 72 0 64 0;
#X connect 73 0 72 0;
#X connect 74 0 65 0;
#X connect 74 1 71 0;
#X connect 74 1 70 0;
#X connect 75 0 76 0;
#X connect 80 1 74 0;

--- NEW FILE: gfsm-help.tfst ---
0	2	42	24	0.7
0	1	2	3	4
1	0

--- NEW FILE: pd_alphabet.c ---
/*=============================================================================*\
 * File: pd_alphabet.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd: alphabet
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_alphabet.h>
#include <pd_io.h>
#include <string.h>

/*=====================================================================
 * DEBUG
 *=====================================================================*/
//#define ALPHABET_DEBUG

/*=====================================================================
 * Pd Constants
 *=====================================================================*/
static t_class *pd_gfsm_alphabet_pd_class;
static t_class *pd_gfsm_alphabet_obj_class;

/*=====================================================================
 * pd_gfsm_alphabet_pd: Methods
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: new
 */
static void *pd_gfsm_alphabet_pd_new(t_symbol *name)
{
    t_pd_gfsm_alphabet_pd *x = (t_pd_gfsm_alphabet_pd *)pd_new(pd_gfsm_alphabet_pd_class);

#ifdef ALPHABET_DEBUG
    post("pd_gfsm_alphabet_pd_new() called ; name=%s ; x=%p",
	 (name ? name->s_name : "(null)"),
	 x);
#endif

    //-- defaults
    x->x_refcnt   = 0;
    x->x_name     = name;
    x->x_alphabet = (gfsmAlphabet*)gfsm_pd_atom_alphabet_new();
    
    //-- bindings
    if (name != &s_) pd_bind((t_pd*)x, name);
    
    return (void *)x;
}


/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: free
 */
static void pd_gfsm_alphabet_pd_free(t_pd_gfsm_alphabet_pd *x)
{
#ifdef ALPHABET_DEBUG
  post("pd_gfsm_alphabet_pd_free() called ; x=%p", x);
#endif

  if (x->x_alphabet) gfsm_pd_atom_alphabet_free((gfsmPdAtomAlphabet*)(x->x_alphabet));

  /* unbind the symbol of the name of hashtable in pd's global namespace */
  if (x->x_name != &s_) pd_unbind((t_pd*)x, x->x_name);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: find
 */
t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_find(t_symbol *name)
{
  if (name != &s_)
    return (t_pd_gfsm_alphabet_pd*)pd_findbyclass(name,pd_gfsm_alphabet_pd_class);
  return NULL;
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: get
 */
t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_get(t_symbol *name)
{
  t_pd_gfsm_alphabet_pd *x = pd_gfsm_alphabet_pd_find(name);
  if (!x) {
    x = (t_pd_gfsm_alphabet_pd*)pd_gfsm_alphabet_pd_new(name);
    x->x_refcnt = 0;
  }
  return x;
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: release
 */
void pd_gfsm_alphabet_pd_release(t_pd_gfsm_alphabet_pd *x)
{
  if (x) {
    if (x->x_refcnt) --x->x_refcnt;
    if (!x->x_refcnt) pd_gfsm_alphabet_pd_free(x);
  }
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_pd: setup
 */
void pd_gfsm_alphabet_pd_setup(void)
{
  //-- class
  pd_gfsm_alphabet_pd_class = class_new(gensym("gfsm_alphabet_pd"),
					(t_newmethod)pd_gfsm_alphabet_pd_new,
					(t_method)pd_gfsm_alphabet_pd_free,
					sizeof(t_pd_gfsm_alphabet_pd),
					CLASS_PD,
					A_DEFSYM,
					A_NULL);
}


/*=====================================================================
 * pd_gfsm_alphabet: Methods
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: new
 */
static void *pd_gfsm_alphabet_obj_new(t_symbol *name)
{
  t_pd_gfsm_alphabet_obj *x = (t_pd_gfsm_alphabet_obj *)pd_new(pd_gfsm_alphabet_obj_class);

#ifdef ALPHABET_DEBUG
  post("pd_gfsm_alphabet_obj_new() called: name=%s ; x=%p",
       (name ? name->s_name : "(null)"),
       x);
#endif

    //-- defaults
    x->x_alphabet_pd = NULL;

    //-- bindings
    x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name);
    x->x_alphabet_pd->x_refcnt++;

    //-- outlets
    x->x_labout = outlet_new(&x->x_obj, &s_float);     //-- label / "char" outlet
    x->x_keyout = outlet_new(&x->x_obj, &s_anything);  //-- atom outlet

    return (void *)x;
}


/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: free
 */
static void pd_gfsm_alphabet_obj_free(t_pd_gfsm_alphabet_obj *x)
{
#ifdef ALPHABET_DEBUG
  post("pd_gfsm_alphabet_obj_free() called: x=%p", x);
#endif

  pd_gfsm_alphabet_pd_release(x->x_alphabet_pd);

  //-- do we need to do this?
  outlet_free(x->x_labout);
  outlet_free(x->x_keyout);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: set
 */
static void pd_gfsm_alphabet_obj_alphabet(t_pd_gfsm_alphabet_obj *x, t_symbol *name)
{
#ifdef ALPHABET_DEBUG
  post("pd_gfsm_alphabet_obj_alphabet() called ; oldname=%p=%s ; newname=%p=%s",
       x->x_alphabet_pd->x_name, x->x_alphabet_pd->x_name->s_name, name, name->s_name);
#endif
  if (name == x->x_alphabet_pd->x_name) return;
  pd_gfsm_alphabet_pd_release(x->x_alphabet_pd);

  x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name);
  ++x->x_alphabet_pd->x_refcnt;
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: load
 */
static void pd_gfsm_alphabet_obj_load(t_pd_gfsm_alphabet_obj *x, t_symbol *s)
{
  gfsmError *errp = NULL;
  gfsm_alphabet_load_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp);
  if (errp != NULL) {
    error("gfsm_alphabet: load %s: %s", s->s_name, errp->message);
    g_error_free(errp);
  }
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: print
 */
static void pd_gfsm_alphabet_obj_print(t_pd_gfsm_alphabet_obj *x)
{
  gfsmError    *errp = NULL;
  gfsmIOHandle *ioh  = pd_gfsm_console_handle_new();
  gfsm_alphabet_save_handle(x->x_alphabet_pd->x_alphabet, ioh, &errp);
  if (errp != NULL) {
    error("gfsm_alphabet: print: %s", errp->message);
    g_error_free(errp);
  }
  pd_gfsm_console_handle_free(ioh);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: save
 */
static void pd_gfsm_alphabet_obj_save(t_pd_gfsm_alphabet_obj *x, t_symbol *s)
{
  gfsmError *errp = NULL;
  gfsm_alphabet_save_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp);
  if (errp != NULL) {
    error("gfsm_alphabet: save %s: %s", s->s_name, errp->message);
    g_error_free(errp);
  }
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: clear
 */
static void pd_gfsm_alphabet_obj_clear(t_pd_gfsm_alphabet_obj *x)
{
  gfsm_alphabet_clear(x->x_alphabet_pd->x_alphabet);
}


/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: outlet_pair
 */
static void pd_gfsm_alphabet_obj_outlet_pair(t_pd_gfsm_alphabet_obj *x, t_float lab, t_atom *a)
{
  if (a) {
    switch (a->a_type) {
    case A_SYMBOL:
      outlet_symbol(x->x_keyout, a->a_w.w_symbol);
      break;
    case A_FLOAT:
      outlet_float(x->x_keyout, a->a_w.w_float);
      break;
    default:
      outlet_symbol(x->x_keyout, atom_getsymbol(a));
      break;
    }
  } else {
    outlet_bang(x->x_keyout);
  }

  if (lab != gfsmNoLabel) outlet_float(x->x_obj.ob_outlet, lab);
  else                    outlet_bang(x->x_obj.ob_outlet);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: insert
 */
static void pd_gfsm_alphabet_obj_insert(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
{
  if (argc < 1) {
    error("pd_gfsm_alphabet_obj_insert(): no atom to insert?");
    return;
  }
  t_float labf = argc > 1 ? atom_getfloat(argv+1) : (t_float)gfsmNoLabel;

  gfsm_alphabet_get_full(x->x_alphabet_pd->x_alphabet, argv, (gfsmLabelVal)labf);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: atom2label
 */
static void pd_gfsm_alphabet_obj_atom2label(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
{
  if (argc < 1) {
    error("pd_gfsm_alphabet_obj_atom2label(): no arguments?");
    return;
  }
  t_float labf = (t_float)(gfsm_alphabet_find_label(x->x_alphabet_pd->x_alphabet, argv));

  pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: atom2label_force
 */
static void pd_gfsm_alphabet_obj_atom2label_force(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
{
  if (argc < 1) {
    error("pd_gfsm_alphabet_obj_atom2label_force(): no arguments?");
    return;
  }
  t_float labf = (t_float)(gfsm_alphabet_get_label(x->x_alphabet_pd->x_alphabet, argv));

  pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: label2atom
 */
static void pd_gfsm_alphabet_obj_label2atom(t_pd_gfsm_alphabet_obj *x, t_float labf)
{
  t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf);

  if (key==NULL) pd_gfsm_alphabet_obj_outlet_pair(x, labf, NULL);
  else           pd_gfsm_alphabet_obj_outlet_pair(x, labf, key);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: label2atom_force
 */
static void pd_gfsm_alphabet_obj_label2atom_force(t_pd_gfsm_alphabet_obj *x, t_float labf)
{
  t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet,
						(gfsmLabelVal)labf);
  if (key==NULL) {
    t_atom labatom;
    SETFLOAT(&labatom, labf);
    gfsm_alphabet_insert(x->x_alphabet_pd->x_alphabet, &labatom, (gfsmLabelVal)labf);
    pd_gfsm_alphabet_obj_outlet_pair(x, labf, &labatom);
  }
  else {
    pd_gfsm_alphabet_obj_outlet_pair(x, labf, key);
  }
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: rmatom()
 */
static void pd_gfsm_alphabet_obj_rmatom(t_pd_gfsm_alphabet_obj *x, t_symbol *sel, int argc, t_atom *argv)
{
  if (argc < 1) return;
  gfsm_alphabet_remove_key(x->x_alphabet_pd->x_alphabet, argv);
}

/*--------------------------------------------------------------------
 * pd_gfsm_alphabet_obj: rmlabel()
 */
static void pd_gfsm_alphabet_obj_rmlabel(t_pd_gfsm_alphabet_obj *x, t_float labf)
{
  gfsm_alphabet_remove_label(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf);
}


/*--------------------------------------------------------------------
 * pd_gfsm_alphabet: setup
 */
void pd_gfsm_alphabet_setup(void)
{
  //-- pd_gfsm_alphabet_pd
  pd_gfsm_alphabet_pd_setup();

  //-- class
  pd_gfsm_alphabet_obj_class = class_new(gensym("gfsm_alphabet"),
			     (t_newmethod)pd_gfsm_alphabet_obj_new,
			     (t_method)pd_gfsm_alphabet_obj_free,
			     sizeof(t_pd_gfsm_alphabet_obj),
			     CLASS_DEFAULT,
			     A_DEFSYM,
			     A_NULL);

  //-- methods: I/O
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_print,
		  gensym("print"),
		  A_NULL);
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_load,
		  gensym("load"),
		  A_SYMBOL,
		  A_NULL);
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_save,
		  gensym("save"),
		  A_SYMBOL,
		  A_NULL);


  //-- methods: whole-object manipulation
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_clear,
		  gensym("clear"),
		  A_NULL);
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_alphabet,
		  gensym("alphabet"),
		  A_DEFSYM,
		  A_NULL);


  //-- methods: insert
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_insert,
		  gensym("insert"),
		  A_GIMME,
		  A_NULL);

  //-- methods: safe access: atom->label
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_atom2label,
		  gensym("atom2char"),
		  A_GIMME,
		  A_NULL);
  /*
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_atom2label,
		  gensym("a2c"),
		  A_GIMME,
		  A_NULL);
  */

  //-- methods: destructive access: atom->label
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_atom2label_force,
		  gensym("atom2char!"),
		  A_GIMME,
		  A_NULL);
  /*
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_atom2label_force,
		  gensym("a2c!"),
		  A_GIMME,
		  A_NULL);
  */


  //-- methods: safe access: label->atom
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_label2atom,
		  gensym("char2atom"),
		  A_FLOAT,
		  A_NULL);
  /*
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_label2atom,
		  gensym("c2a"),
		  A_FLOAT,
		  A_NULL);
  */

  //-- methods: destructive access: label->atom
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_label2atom_force,
		  gensym("char2atom!"),
		  A_FLOAT,
		  A_NULL);
  /*
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_label2atom_force,
		  gensym("c2a!"),
		  A_FLOAT,
		  A_NULL);
  */

  //-- methods: removal
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_rmatom,
		  gensym("rmatom"),
		  A_GIMME,
		  A_NULL);
  class_addmethod(pd_gfsm_alphabet_obj_class,
		  (t_method)pd_gfsm_alphabet_obj_rmlabel,
		  gensym("rmchar"),
		  A_FLOAT,
		  A_NULL);
  

  //-- help symbol
  class_sethelpsymbol(pd_gfsm_alphabet_obj_class, gensym("gfsm_alphabet-help.pd"));
}

--- NEW FILE: gfsm_alphabet-help.pd ---
#N canvas 16 0 646 547 10;
#X text 289 523 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X text 9 524 SEE ALSO:;
#X text 9 69 INLETS:;
#X text 27 83 1 - control messages;
#X text 244 68 OUTLETS:;
#X obj 80 525 gfsm;
#X text 48 48 NAME - symbolic name of the alphabet;
#X text 260 81 1 - value outlet;
#X text 260 96 2 - bang on missing value;
#X text 14 31 SYNTAX: gfsm_alphabet [NAME];
#X obj 13 493 print CHAR;
#X obj 197 492 print ATOM;
#X msg 29 182 insert x 1;
#X text 163 185 "insert ATOM CHAR" : map ATOM<->CHAR;
#X msg 33 203 insert y;
#X text 198 203 "insert ATOM" : map ATOM to a new character label;
#X msg 48 232 atom2char x;
#X text 177 233 "atom2char ATOM" : lookup character label for ATOM
;
#X text 170 253 "atom2char! ATOM" : lookup or insert label for ATOM
;
#X text 184 284 "char2atom INT" : lookup atom for label INT;
#X text 177 301 "char2atom! INT" : lookup or insert atom for INT;
#X msg 63 281 char2atom 1;
#X msg 65 301 char2atom! 42;
#X msg 52 252 atom2char! foo;
#X text 184 129 "alphabet NAME" : sets current alphabet;
#X msg 19 151 alphabet;
#X text 219 145 "alphabet" : use private alphabet;
#X text 309 159 NOTE: alphabets of the same name share data;
#X msg 75 332 clear;
#X msg 91 405 print;
#X text 240 404 "print" : dump alphabet contents to the console;
#X msg 91 445 save tmp.lab;
#X text 212 425 "load FILE" : load alphabet contents from a file;
#X text 212 445 "save FILE" : save alphabet contents to a file;
#X text 67 4 gfsm_alphabet : integer<->atom map for finite state machines
;
#X text 240 333 "clear" : clears entire alphabet;
#X msg 76 353 rmatom x;
#X msg 77 374 rmchar 1;
#X text 205 372 "rmchar INT" : remove mapping for label INT;
#X text 198 353 "rmatom ATOM" : remove mapping for atom ATOM;
#X obj 117 525 gfsm_automaton;
#X obj 13 471 gfsm_alphabet help-alphabet;
#X msg 13 127 alphabet help-alphabet;
#X msg 92 425 load tmp.lab;
#X connect 12 0 41 0;
#X connect 14 0 41 0;
#X connect 16 0 41 0;
#X connect 21 0 41 0;
#X connect 22 0 41 0;
#X connect 23 0 41 0;
#X connect 25 0 41 0;
#X connect 28 0 41 0;
#X connect 29 0 41 0;
#X connect 31 0 41 0;
#X connect 36 0 41 0;
#X connect 37 0 41 0;
#X connect 41 0 10 0;
#X connect 41 1 11 0;
#X connect 42 0 41 0;
#X connect 43 0 41 0;

--- NEW FILE: gfsm_markov.pd ---
#N canvas 386 0 450 300 10;
#X text 85 2 gfsm_markov : Markov chain using gfsm;
#X text 181 17 for details \, see:;
#N canvas 266 0 499 471 gfsm_markov_doc 0;
#X text 85 2 gfsm_markov : Markov chain using gfsm;
#X text 15 67 INLETS:;
#X text 28 84 1 - control messages;
#X text 203 64 OUTLETS:;
#X text 17 128 MESSAGES:;
#X text 81 219 set ATOM : set current state to ATOM;
#X text 116 231 set : reset to initial (root) state;
#X text 107 441 bang : synonym for "next";
#X text 16 24 SYNTAX: gfsm_markov OBJNAME;
#X text 15 44 REQUIRES:;
#X obj 83 44 gfsm;
#X text 75 147 load BASE : load text files BASE.lab and BASE.tfst;
#X text 75 159 save BASE : save text files BASE.lab \, BASE.tfst;
#X text 47 182 load_bin BASE : load files BASE.lab \, BASE.gfst;
#X text 47 194 save_bin BASE : save files BASE.lab \, BASE.gfst;
#X obj 121 45 zexy;
#X text 156 294 from current state \, and move to;
#X text 23 281 add A1 A2 WEIGHT : add WEIGHT to arc on atom-pair A1:A2
;
#X text 73 411 next PROB : get next arc with PROB as nearest probability
;
#X text 107 427 next : get next arc with random probability;
#X text 216 106 3 - bang when stuck;
#X text 157 330 + WEIGHT defaults to 1;
#X text 157 318 + A2 defaults to 0 (epsilon);
#X text 157 378 + WEIGHT defaults to 1;
#X text 157 366 + A2 defaults to 0 (epsilon);
#X text 18 354 addi A1 A2 WEIGHT : add WEIGHT to initial arc on atoms
A1:A2;
#X text 156 305 (possibly new) state for atom A1;
#X text 217 92 2 - upper side atoms on "next";
#X text 217 78 1 - lower side atoms on "next";
#X text 102 250 clear : clear underlying objects;
#X restore 309 19 pd gfsm_markov_doc;
#X obj 20 60 inlet;
#X obj 22 261 outlet;
#X obj 103 260 outlet;
#N canvas 27 71 720 463 gfsm_markov_control_guts 0;
#X obj 22 8 inlet;
#X obj 450 32 print gfsm_markov_bad_message;
#X obj 183 230 s \$0-load;
#X obj 215 209 s \$0-save;
#X obj 247 187 s \$0-load_bin;
#X obj 280 164 s \$0-save_bin;
#X obj 86 373 s \$0-set;
#X obj 312 125 s \$0-clear;
#X obj 118 337 s \$0-add;
#X obj 22 409 s \$0-next;
#X obj 303 99 s \$0-fsm;
#X obj 335 78 s \$0-alph;
#X obj 151 295 s \$0-addi;
#X obj 415 79 s \$0-state-r;
#X obj 22 28 route next bang set add addi load save load_bin save_bin
clear fsm alph state add2;
#X obj 449 122 s \$0-add2;
#X connect 0 0 14 0;
#X connect 14 0 9 0;
#X connect 14 1 9 0;
#X connect 14 2 6 0;
#X connect 14 3 8 0;
#X connect 14 4 12 0;
#X connect 14 5 2 0;
#X connect 14 6 3 0;
#X connect 14 7 4 0;
#X connect 14 8 5 0;
#X connect 14 9 7 0;
#X connect 14 10 10 0;
#X connect 14 11 11 0;
#X connect 14 12 13 0;
#X connect 14 13 15 0;
#X connect 14 14 1 0;
#X restore 20 82 pd gfsm_markov_control_guts;
#N canvas 0 252 310 205 gfsm_markov_fsm_guts 0;
#X obj 40 121 gfsm_automaton \$1-fsm;
#X obj 40 53 gfsm_alphabet \$1-alph;
#X obj 40 100 r \$0-fsm;
#X obj 40 33 r \$0-alph;
#X connect 2 0 0 0;
#X connect 3 0 1 0;
#X restore 21 113 pd gfsm_markov_fsm_guts;
#N canvas 114 67 710 486 gfsm_markov_io_guts 0;
#X obj 21 87 symbol;
#X msg 209 301 load \$1;
#X obj 178 86 symbol;
#X msg 556 308 save \$1;
#X msg 21 215 load \$1;
#X obj 367 85 symbol;
#X obj 526 79 symbol;
#X obj 21 20 r \$0-load;
#X obj 367 22 r \$0-save;
#X obj 526 26 r \$0-save_bin;
#X obj 178 19 r \$0-load_bin;
#X obj 21 110 t s s;
#X obj 178 106 t s s;
#X obj 367 107 t s s;
#X obj 526 100 t s s;
#X msg 179 215 load_bin \$1;
#X msg 526 216 save_bin \$1;
#X msg 367 215 save \$1;
#X obj 21 193 makefilename %s.tfst;
#X obj 178 192 makefilename %s.gfst;
#X obj 367 193 makefilename %s.tfst;
#X obj 526 193 makefilename %s.gfst;
#X obj 556 286 makefilename %s.lab;
#X obj 209 280 makefilename %s.lab;
#X obj 179 434 s \$0-fsm;
#X obj 367 429 s \$0-alph;
#X connect 0 0 11 0;
#X connect 1 0 25 0;
#X connect 2 0 12 0;
#X connect 3 0 25 0;
#X connect 4 0 24 0;
#X connect 5 0 13 0;
#X connect 6 0 14 0;
#X connect 7 0 0 0;
#X connect 8 0 5 0;
#X connect 9 0 6 0;
#X connect 10 0 2 0;
#X connect 11 0 18 0;
#X connect 11 1 23 0;
#X connect 12 0 19 0;
#X connect 12 1 23 0;
#X connect 13 0 20 0;
#X connect 13 1 22 0;
#X connect 14 0 21 0;
#X connect 14 1 22 0;
#X connect 15 0 24 0;
#X connect 16 0 24 0;
#X connect 17 0 24 0;
#X connect 18 0 4 0;
#X connect 19 0 15 0;
#X connect 20 0 17 0;
#X connect 21 0 16 0;
#X connect 22 0 3 0;
#X connect 23 0 1 0;
#X restore 21 138 pd gfsm_markov_io_guts;
#N canvas 150 351 551 242 gfsm_markov_set_guts 0;
#X obj 32 18 r \$0-set;
#X obj 32 40 route bang;
#X obj 97 133 gfsm_alphabet \$1-alph;
#X obj 97 61 route float list;
#X msg 97 110 atom2char! \$1;
#X obj 204 83 symbol;
#X msg 97 156 set \$1;
#X obj 97 178 s \$0-state;
#X msg 32 83 0;
#X obj 345 15 r \$0-clear;
#X obj 389 78 s \$0-alph;
#X obj 367 126 s \$0-fsm;
#X msg 367 105 clear \, root 0;
#X msg 389 57 clear \, atom2char! 0;
#X obj 345 35 t b b b;
#X msg 345 150 set 0;
#X obj 346 170 s \$0-state;
#X connect 0 0 1 0;
#X connect 1 0 8 0;
#X connect 1 1 3 0;
#X connect 2 0 6 0;
#X connect 3 0 4 0;
#X connect 3 1 4 0;
#X connect 3 2 5 0;
#X connect 4 0 2 0;
#X connect 5 0 4 0;
#X connect 6 0 7 0;
#X connect 8 0 4 0;
#X connect 9 0 14 0;
#X connect 12 0 11 0;
#X connect 13 0 10 0;
#X connect 14 0 15 0;
#X connect 14 1 12 0;
#X connect 14 2 13 0;
#X connect 15 0 16 0;
#X restore 21 162 pd gfsm_markov_set_guts;
#X obj 261 60 loadbang;
#N canvas 142 144 416 223 gfsm_markov_init_guts 0;
#X obj 15 9 inlet;
#X msg 15 97 char2atom! 0;
#X obj 15 118 s \$0-alph;
#X obj 15 66 t b b;
#X obj 74 10 r \$0-loadbang;
#X obj 179 124 gfsm_automaton \$1-fsm;
#X msg 206 97 root;
#X obj 179 145 route root;
#X obj 179 168 route bang;
#X msg 155 98 root 0;
#X connect 0 0 3 0;
#X connect 1 0 2 0;
#X connect 3 0 1 0;
#X connect 3 1 6 0;
#X connect 4 0 3 0;
#X connect 5 0 7 0;
#X connect 6 0 5 0;
#X connect 7 0 8 0;
#X connect 8 0 9 0;
#X connect 9 0 5 0;
#X restore 261 81 pd gfsm_markov_init_guts;
#N canvas 66 12 666 508 gfsm_markov_add_guts 0;
#X obj 28 231 gfsm_alphabet \$1-alph;
#X obj 28 167 route float list;
#X msg 28 211 atom2char! \$1;
#X obj 95 190 symbol;
#X obj 58 426 gfsm_state \$1-fsm;
#X obj 71 402 r \$0-state;
#X msg 508 322 set \$1;
#X obj 508 428 s \$0-state;
#X obj 28 12 r \$0-add1;
#X obj 121 12 r \$0-add;
#X obj 123 320 1;
#X obj 28 260 t f f;
#X obj 413 14 r \$0-addi1;
#X obj 492 14 r \$0-addi;
#X obj 443 89 gfsm_automaton \$1-fsm;
#X msg 443 67 root;
#X obj 413 39 t a b;
#X obj 443 110 route root;
#X obj 443 132 route bang;
#X msg 481 67 root 0;
#X msg 58 372 add_weight \$1 \$1 \$2 \$3;
#X obj 28 89 t a b b;
#X obj 58 347 pack 0 0 0;
#X obj 90 320 0;
#X text 139 347 <-- Q=LO HI WEIGHT;
#X obj 28 112 niagara 1;
#X obj 231 129 niagara 1;
#X obj 231 236 gfsm_alphabet \$1-alph;
#X obj 231 172 route float list;
#X msg 231 216 atom2char! \$1;
#X obj 298 195 symbol;
#X obj 204 12 r \$0-add2;
#X obj 28 42 t a b;
#X obj 205 35 t a b;
#X obj 446 297 spigot;
#X obj 454 273 0;
#X obj 479 273 1;
#X connect 0 0 11 0;
#X connect 1 0 2 0;
#X connect 1 1 2 0;
#X connect 1 2 3 0;
#X connect 2 0 0 0;
#X connect 3 0 2 0;
#X connect 5 0 4 0;
#X connect 6 0 7 0;
#X connect 8 0 32 0;
#X connect 9 0 32 0;
#X connect 10 0 22 2;
#X connect 11 0 34 0;
#X connect 11 1 22 0;
#X connect 12 0 16 0;
#X connect 13 0 16 0;
#X connect 14 0 17 0;
#X connect 15 0 14 0;
#X connect 16 0 21 0;
#X connect 16 1 15 0;
#X connect 17 0 18 0;
#X connect 18 0 19 0;
#X connect 18 1 6 0;
#X connect 19 0 14 0;
#X connect 20 0 4 0;
#X connect 21 0 25 0;
#X connect 21 1 23 0;
#X connect 21 2 10 0;
#X connect 22 0 20 0;
#X connect 23 0 22 1;
#X connect 25 0 1 0;
#X connect 25 1 26 0;
#X connect 26 0 28 0;
#X connect 26 1 22 2;
#X connect 27 0 22 1;
#X connect 28 0 29 0;
#X connect 28 1 29 0;
#X connect 28 2 30 0;
#X connect 29 0 27 0;
#X connect 30 0 29 0;
#X connect 31 0 33 0;
#X connect 32 0 21 0;
#X connect 32 1 36 0;
#X connect 33 0 21 0;
#X connect 33 1 35 0;
#X connect 34 0 6 0;
#X connect 35 0 34 1;
#X connect 36 0 34 1;
#X restore 21 186 pd gfsm_markov_add_guts;
#N canvas 27 0 738 524 gfsm_markov_next_guts 0;
#X obj 86 25 r \$0-next;
#X obj 243 464 outlet;
#X obj 86 47 route bang;
#X obj 151 158 * -1;
#X obj 151 136 * 1;
#X obj 559 376 t b b;
#N canvas 75 18 312 424 weight_sum 0;
#X obj 24 9 inlet;
#X msg 24 114 arc_next;
#X obj 24 319 f 0;
#X obj 199 92 0;
#X obj 89 238 unpack 0 0 0 0;
#X obj 183 262 + 0;
#X obj 88 263 t f f;
#X obj 24 350 outlet;
#X obj 60 146 r \$0-state;
#X obj 24 90 until;
#X obj 24 214 route bang;
#X obj 24 235 t b b;
#X obj 24 192 route arc_next;
#X obj 24 43 t b b b b;
#X msg 91 114 arc_reset;
#X obj 24 167 gfsm_state \$1-fsm 0;
#X connect 0 0 13 0;
#X connect 1 0 15 0;
#X connect 2 0 7 0;
#X connect 3 0 5 1;
#X connect 4 3 5 0;
#X connect 5 0 6 0;
#X connect 6 0 5 1;
#X connect 6 1 2 1;
#X connect 8 0 15 0;
#X connect 9 0 1 0;
#X connect 10 0 11 0;
#X connect 10 1 4 0;
#X connect 11 0 2 0;
#X connect 11 1 9 1;
#X connect 12 0 10 0;
#X connect 13 0 9 0;
#X connect 13 1 3 0;
#X connect 13 2 14 0;
#X connect 13 3 9 1;
#X connect 14 0 15 0;
#X connect 15 0 12 0;
#X restore 167 115 pd weight_sum;
#X obj 25 95 random 131072;
#X obj 25 116 / 131072;
#X obj 86 69 t b b b;
#X obj 151 69 t f b b;
#X msg 559 227 arc_next;
#X obj 594 269 r \$0-state;
#X obj 559 205 until;
#X obj 559 349 route bang;
#X obj 559 326 route arc_next;
#X msg 625 226 arc_reset;
#X obj 151 180 t b b f;
#X obj 405 461 outlet;
#X obj 101 429 gfsm_alphabet \$1-alph;
#X msg 101 407 char2atom! \$1;
#X obj 179 296 moses 0;
#X obj 179 251 + 0;
#X obj 179 274 t f f;
#X obj 86 225 unpack 0 0 0 0;
#X obj 18 386 f 0;
#X msg 18 411 set \$1;
#X obj 18 432 s \$0-state;
#X obj 559 292 gfsm_state \$1-fsm 0;
#X obj 559 457 outlet;
#X obj 263 428 gfsm_alphabet \$1-alph;
#X msg 263 406 char2atom! \$1;
#X obj 263 384 f 0;
#X obj 101 385 f 0;
#X obj 225 316 t b b b b;
#X connect 0 0 2 0;
#X connect 2 0 9 0;
#X connect 2 1 10 0;
#X connect 3 0 17 0;
#X connect 4 0 3 0;
#X connect 5 0 29 0;
#X connect 5 1 13 1;
#X connect 6 0 4 1;
#X connect 7 0 8 0;
#X connect 8 0 4 0;
#X connect 9 0 7 0;
#X connect 9 1 6 0;
#X connect 9 2 13 1;
#X connect 10 0 4 0;
#X connect 10 1 6 0;
#X connect 10 2 13 1;
#X connect 11 0 28 0;
#X connect 12 0 28 0;
#X connect 13 0 11 0;
#X connect 14 0 5 0;
#X connect 14 1 24 0;
#X connect 15 0 14 0;
#X connect 16 0 28 0;
#X connect 17 0 13 0;
#X connect 17 1 16 0;
#X connect 17 2 22 1;
#X connect 19 1 1 0;
#X connect 20 0 19 0;
#X connect 21 1 34 0;
#X connect 22 0 23 0;
#X connect 23 0 21 0;
#X connect 23 1 22 1;
#X connect 24 0 25 1;
#X connect 24 1 33 1;
#X connect 24 2 32 1;
#X connect 24 3 22 0;
#X connect 25 0 26 0;
#X connect 26 0 27 0;
#X connect 28 0 15 0;
#X connect 30 1 18 0;
#X connect 31 0 30 0;
#X connect 32 0 31 0;
#X connect 33 0 20 0;
#X connect 34 0 25 0;
#X connect 34 1 33 0;
#X connect 34 2 32 0;
#X connect 34 3 13 1;
#X restore 22 216 pd gfsm_markov_next_guts;
#X obj 185 260 outlet;
#X connect 3 0 6 0;
#X connect 10 0 11 0;
#X connect 13 0 4 0;
#X connect 13 1 5 0;
#X connect 13 2 14 0;

--- NEW FILE: pd_algebra.c ---
/*=============================================================================*\
 * File: pd_algebra.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_gfsm.h>
#include <pd_automaton.h>
#include <m_pd.h>

/*--------------------------------------------------------------------
 * DEBUG
 *--------------------------------------------------------------------*/
//#define PDFSM_DEBUG 1

/*=====================================================================
 * Structures and Types
 *=====================================================================*/
//(none)

/*=====================================================================
 * pd_gfsm_automaton_obj: Utilities
 *=====================================================================*/
//(none)

/*=====================================================================
 * pd_gfsm_automaton_obj: Algebra
 *=====================================================================*/

/*--------------------------------------------------------------------
 * complement
 */
static void pd_gfsm_automaton_complement(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_complement(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("complement"));
}

/*--------------------------------------------------------------------
 * closure
 */
static void pd_gfsm_automaton_closure(t_pd_gfsm_automaton_obj *x, t_float nf)
{
  gfsm_automaton_n_closure(x->x_automaton_pd->x_automaton, (guint)nf);
  pd_gfsm_automaton_obj_outlet_float(x, gensym("closure"), nf);
}

/*--------------------------------------------------------------------
 * compose
 */
static void pd_gfsm_automaton_compose(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_compose(): no fsm named '%s'", fsm2_name->s_name);
    return;
  } else {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_compose(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("compose"), fsm2_name);
}

/*--------------------------------------------------------------------
 * concat
 */
static void pd_gfsm_automaton_concat(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_concat(): no fsm named '%s'", fsm2_name->s_name);
    return;
  } else {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_concat(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("concat"), fsm2_name);
}

/*--------------------------------------------------------------------
 * determinize
 */
static void pd_gfsm_automaton_determinize(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_determinize(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("determinize"));
}

/*--------------------------------------------------------------------
 * difference
 */
static void pd_gfsm_automaton_difference(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_difference(): no fsm named '%s'", fsm2_name->s_name);
    return;
  } else {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_difference(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("difference"), fsm2_name);
}

/*--------------------------------------------------------------------
 * intersection
 */
static void pd_gfsm_automaton_intersect(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_intersect(): no fsm named '%s'", fsm2_name->s_name);
    return;
  } else {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_intersect(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("intersect"), fsm2_name);
}

/*--------------------------------------------------------------------
 * invert
 */
static void pd_gfsm_automaton_invert(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_invert(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("invert"));
}

/*--------------------------------------------------------------------
 * product
 */
static void pd_gfsm_automaton_product(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_product(): no fsm named '%s'", fsm2_name->s_name);
    return;
  } else {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_product(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("intersect"), fsm2_name);
}

/*--------------------------------------------------------------------
 * project
 */
static void pd_gfsm_automaton_project(t_pd_gfsm_automaton_obj *x, t_float which)
{
  gfsm_automaton_project(x->x_automaton_pd->x_automaton,
			 (which==0 ? gfsmLSLower : gfsmLSUpper));
  pd_gfsm_automaton_obj_outlet_float(x, gensym("project"), which);
}

/*--------------------------------------------------------------------
 * prune
 */
static void pd_gfsm_automaton_connect(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_connect(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("connect"));
}

/*--------------------------------------------------------------------
 * renumber
 */
static void pd_gfsm_automaton_renumber(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_renumber_states(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("renumber"));
}


/*--------------------------------------------------------------------
 * reverse
 */
static void pd_gfsm_automaton_reverse(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_reverse(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("reverse"));
}

/*--------------------------------------------------------------------
 * rmepsilon
 */
static void pd_gfsm_automaton_rmepsilon(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_rmepsilon(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("rmepsilon"));
}

/*--------------------------------------------------------------------
 * union
 */
static void pd_gfsm_automaton_union(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
{
  t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
  if (!fsm2_pd) {
    error("pd_gfsm_automaton_union(): no fsm named '%s'", fsm2_name->s_name);
    return;
  }
  else if (fsm2_pd != x->x_automaton_pd) {
    ++fsm2_pd->x_refcnt;
    gfsm_automaton_union(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
    pd_gfsm_automaton_pd_release(fsm2_pd);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("union"), fsm2_name);
}


/*=====================================================================
 * setup
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: setup()
 */
void pd_gfsm_algebra_setup(t_class *automaton_class)
{
  //-- methods: algebra
  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_complement,
		  gensym("complement"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_closure,
		  gensym("closure"), A_DEFFLOAT, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_compose,
		  gensym("compose"), A_SYMBOL, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_concat,
		  gensym("concat"), A_SYMBOL, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_determinize,
		  gensym("determinize"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_difference,
		  gensym("difference"), A_SYMBOL, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_intersect,
		  gensym("intersect"), A_SYMBOL, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_invert,
		  gensym("invert"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_product,
		  gensym("product"), A_SYMBOL, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_project,
		  gensym("project"), A_DEFFLOAT, A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_connect,
		  gensym("connect"), A_NULL);
  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_connect,
		  gensym("prune"), A_NULL); //-- backwards-compatible alias


  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_renumber,
		  gensym("renumber"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_reverse,
		  gensym("reverse"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_rmepsilon,
		  gensym("rmepsilon"), A_NULL);

  class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_union,
		  gensym("union"), A_SYMBOL, A_NULL);
}

--- NEW FILE: pd_automaton.h ---
/*=============================================================================*\
 * File: pd_automaton.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

/*=====================================================================
 * Protos
 *=====================================================================*/
#ifndef PD_GFSM_AUTOMATON_H
#define PD_GFSM_AUTOMATON_H

/*----------------------------------------------------------------------
 * includes
 */
#include <m_pd.h>
#include <gfsm.h>
#include <pd_alphabet.h>

/*--------------------------------------------------------------
 * pd_fsm_automaton_pd
 */
typedef struct _pd_gfsm_automaton_pd
{
  t_pd             x_pd;
  t_symbol        *x_name;
  size_t           x_refcnt;
  gfsmAutomaton   *x_automaton;
} t_pd_gfsm_automaton_pd;

typedef struct _pd_gfsm_automaton_obj
{
  t_object                 x_obj;
  t_pd_gfsm_automaton_pd  *x_automaton_pd;
  t_atom                   x_argv[5];
  t_outlet                *x_valout;
} t_pd_gfsm_automaton_obj;

/*--------------------------------------------------------------------
 * utility macros
 */
#define atom_getboolarg(which,argc,argv) (atom_getintarg(which,argc,argv)==0 ? FALSE : TRUE)
#define GIMME_ARGS t_symbol *sel, int argc, t_atom *argv

/*----------------------------------------------------------------------
 * utilities
 */
t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_find(t_symbol *name);
t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_get(t_symbol *name);
void pd_gfsm_automaton_pd_release(t_pd_gfsm_automaton_pd *x);

void pd_gfsm_automaton_obj_outlet_symbol(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *val);
void pd_gfsm_automaton_obj_outlet_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f);
void pd_gfsm_automaton_obj_outlet_float_2(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f1, t_float f2);
void pd_gfsm_automaton_obj_outlet_bang(t_pd_gfsm_automaton_obj *x, t_symbol *sel);

/*----------------------------------------------------------------------
 * setup routines
 */
extern void pd_gfsm_algebra_setup(t_class *automaton_class);

void pd_gfsm_automaton_setup(void);

#endif /* PD_GFSM_AUTOMATON_H */

--- NEW FILE: pd_state.c ---
/*=============================================================================*\
 * File: pd_state.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_state.h>

/*=====================================================================
 * Structures and Types
 *=====================================================================*/
static t_class *pd_gfsm_state_class;


/*=====================================================================
 * pd_gfsm_state: Methods
 *=====================================================================*/

/*=====================================================================
 * Constructors, etc.
 */

/*--------------------------------------------------------------------
 * new()
 */
static void *pd_gfsm_state_new(t_symbol *sel, int argc, t_atom *argv)
{
  t_symbol *name = &s_;
  t_pd_gfsm_state *x = (t_pd_gfsm_state *)pd_new(pd_gfsm_state_class);

  //-- defaults
  x->x_id = gfsmNoState;
  gfsm_arciter_close(&x->x_arci);
  x->x_open = FALSE;

  //-- args
  if (argc > 0) {
    name = atom_getsymbolarg(0,argc,argv);
    if (argc > 1) x->x_id = (gfsmStateId)atom_getfloatarg(1,argc,argv);
  }

  //-- bindings
  x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
  x->x_automaton_pd->x_refcnt++;

  //-- outlets
  x->x_valout = outlet_new(&x->x_obj, &s_anything);  //-- value outlet

  return (void *)x;
}

/*--------------------------------------------------------------------
 * free
 */
static void pd_gfsm_state_free(t_pd_gfsm_state *x)
{
  gfsm_arciter_close(&x->x_arci);
  pd_gfsm_automaton_pd_release(x->x_automaton_pd);

  //-- do we need to do this?
  outlet_free(x->x_valout);
}

/*=====================================================================
 * Basic Accessors
 */

/*--------------------------------------------------------------------
 * automaton
 */
static void pd_gfsm_state_automaton(t_pd_gfsm_state *x, t_symbol *name)
{
  gfsm_arciter_close(&x->x_arci);
  x->x_open = FALSE;

  if (name == x->x_automaton_pd->x_name) return;
  pd_gfsm_automaton_pd_release(x->x_automaton_pd);

  x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
  ++x->x_automaton_pd->x_refcnt;
}


/*--------------------------------------------------------------------
 * id
 */
static void pd_gfsm_state_id(t_pd_gfsm_state *x)
{
  SETSYMBOL(x->x_argv, gensym("id"));
  if (x->x_id==gfsmNoState) SETSYMBOL(x->x_argv, &s_bang);
  else                      SETFLOAT(x->x_argv, (t_float)(x->x_id));
  outlet_anything(x->x_valout, gensym("id"), 1, x->x_argv);
}

/*--------------------------------------------------------------------
 * set
 */
static void pd_gfsm_state_set(t_pd_gfsm_state *x, t_floatarg qf)
{
  if (qf<0) qf = -qf;
  gfsm_arciter_close(&x->x_arci);
  x->x_open = FALSE;
  x->x_id   = gfsm_automaton_ensure_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf);
}

/*--------------------------------------------------------------------
 * degree
 */
static void pd_gfsm_state_degree(t_pd_gfsm_state *x)
{
  gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
  SETFLOAT(x->x_argv, (s ? (t_float)gfsm_state_out_degree(s) : 0));
  outlet_anything(x->x_valout, gensym("degree"), 1, x->x_argv);
}

/*=====================================================================
 * Navigation
 */

/*--------------------------------------------------------------------
 * utility: outlet_arc()
 */
static void pd_gfsm_state_outlet_arc(t_pd_gfsm_state *x, t_symbol *sel)
{
  //outlet_anything(x->x_opout, op, 0, NULL);
  if (gfsm_arciter_ok(&x->x_arci)) {
    gfsmArc *a = gfsm_arciter_arc(&x->x_arci);
    SETFLOAT(x->x_argv,   (t_float)(a->target));
    SETFLOAT(x->x_argv+1, (t_float)(a->lower));
    SETFLOAT(x->x_argv+2, (t_float)(a->upper));
    SETFLOAT(x->x_argv+3, (t_float)(a->weight));
    outlet_anything(x->x_valout, sel, 4, x->x_argv);
  }
  else {
    SETSYMBOL(x->x_argv, &s_bang);
    outlet_anything(x->x_valout, sel, 1, x->x_argv);
  }
}

/*--------------------------------------------------------------------
 * arc_first
 */
static void pd_gfsm_state_arc_first(t_pd_gfsm_state *x)
{
  gfsm_arciter_close(&x->x_arci);
  gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
  x->x_open = TRUE;
  pd_gfsm_state_outlet_arc(x, gensym("arc_first"));
}

/*--------------------------------------------------------------------
 * arc_next
 */
static void pd_gfsm_state_arc_next(t_pd_gfsm_state *x)
{
  gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
  if (s) {
    if (x->x_open && gfsm_arciter_ok(&x->x_arci)) {
      gfsm_arciter_next(&x->x_arci);
    } else if (!x->x_open) {
      gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
      x->x_open = TRUE;
    }
  }
  pd_gfsm_state_outlet_arc(x, gensym("arc_next"));
}

/*--------------------------------------------------------------------
 * arc_seek
 */
static void pd_gfsm_state_arc_seek(t_pd_gfsm_state *x, t_float flo, t_float fhi)
{
  gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
  if (s) {
    if (x->x_open && gfsm_arciter_ok(&x->x_arci)) {
      gfsm_arciter_next(&x->x_arci);
    } else if (!x->x_open) {
      gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
      x->x_open = TRUE;
    }
  }
  gfsm_arciter_seek_both(&x->x_arci,
			 (flo < 0 ? gfsmNoLabel : ((gfsmLabelVal)flo)),
			 (fhi < 0 ? gfsmNoLabel : ((gfsmLabelVal)fhi)));
  pd_gfsm_state_outlet_arc(x, gensym("arc_seek"));
}


/*--------------------------------------------------------------------
 * arc_reset
 */
static void pd_gfsm_state_arc_reset(t_pd_gfsm_state *x)
{
  gfsm_arciter_close(&x->x_arci);
  x->x_open = FALSE;
}

/*--------------------------------------------------------------------
 * add_weight
 */
static void pd_gfsm_state_add_weight(t_pd_gfsm_state *x,
				     t_float fto,
				     t_float flo,
				     t_float fhi,
				     t_float w)
{
  gfsmStateId  to = (fto < 0 ? (-fto)      : ((gfsmStateId)fto));
  gfsmLabelVal lo = (flo < 0 ? gfsmNoLabel : ((gfsmLabelVal)flo));
  gfsmLabelVal hi = (fhi < 0 ? gfsmNoLabel : ((gfsmLabelVal)fhi));

  if (x->x_open) pd_gfsm_state_arc_reset(x);

  gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
  gfsm_arciter_seek_both(&x->x_arci, lo, hi);

  if (gfsm_arciter_ok(&x->x_arci)) {
    gfsm_arciter_arc(&x->x_arci)->weight += w;
  } else {
    if (lo==gfsmNoLabel) lo = gfsmEpsilon;
    if (hi==gfsmNoLabel) hi = gfsmEpsilon;
    gfsm_automaton_add_arc(x->x_automaton_pd->x_automaton, x->x_id, to, lo, hi, w);
  }

  pd_gfsm_state_arc_reset(x);
}



/*=====================================================================
 * Setup
 */

/*--------------------------------------------------------------------
 * setup()
 */
void pd_gfsm_state_setup(void)
{
  //-- class
  pd_gfsm_state_class = class_new(gensym("gfsm_state"),
				  (t_newmethod)pd_gfsm_state_new,
				  (t_method)pd_gfsm_state_free,
				  sizeof(t_pd_gfsm_state),
				  CLASS_DEFAULT,
				  A_GIMME, A_NULL);

  //-- methods: automaton
  class_addmethod(pd_gfsm_state_class,
		  (t_method)pd_gfsm_state_automaton,
		  gensym("automaton"),
		  A_DEFSYM, A_NULL);

  //-- methods: id
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_id,
		  gensym("id"), A_NULL);
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_set,
		  gensym("set"), A_DEFFLOAT, A_NULL);

  //-- methods: degree
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_degree,
		  gensym("degree"), A_NULL);

  //-- methods: navigation
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_first,
		  gensym("arc_first"), A_NULL);
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_next,
		  gensym("arc_next"), A_NULL);
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_seek,
		  gensym("arc_seek"), A_FLOAT, A_FLOAT, A_NULL);
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_reset,
		  gensym("arc_reset"), A_NULL);

  //-- methods: manipulation
  class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_add_weight,
		  gensym("add_weight"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);

  //-- help symbol
  class_sethelpsymbol(pd_gfsm_state_class, gensym("gfsm_state-help.pd"));
}

--- NEW FILE: test3.tfst ---
0	1	3	30	0.3
0	2	4	40	0.7
1	0
2	0

--- NEW FILE: pd_automaton.c ---
/*=============================================================================*\
 * File: pd_automaton.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <pd_automaton.h>
#include <pd_io.h>
#include <m_pd.h>

/*--------------------------------------------------------------------
 * DEBUG
 *--------------------------------------------------------------------*/
//#define PDFSM_DEBUG 1

/*=====================================================================
 * Structures and Types
 *=====================================================================*/
static t_class *pd_gfsm_automaton_pd_class;
static t_class *pd_gfsm_automaton_obj_class;

/*=====================================================================
 * pd_gfsm_automaton_pd: Methods
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_pd: new()
 */
static void *pd_gfsm_automaton_pd_new(t_symbol *name)
{
    t_pd_gfsm_automaton_pd *x = (t_pd_gfsm_automaton_pd *)pd_new(pd_gfsm_automaton_pd_class);

    //-- debug
#ifdef PDFSM_DEBUG
    post("pd_gfsm_automaton_pd_new() called; name=%s ; x=%p\n", name->s_name, x);
#endif

    //-- defaults
    x->x_refcnt    = 0;
    x->x_name      = name;
    x->x_automaton = gfsm_automaton_new();

    //-- bindings
    if (name != &s_) pd_bind((t_pd*)x, name);

    return (void *)x;
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_pd: free()
 */
static void pd_gfsm_automaton_pd_free(t_pd_gfsm_automaton_pd *x)
{
#ifdef PDFSM_DEBUG
  post("pd_gfsm_automaton_pd_free() called ; x=%p", x);
#endif

  if (x->x_automaton) gfsm_automaton_free(x->x_automaton);
  x->x_automaton = NULL;

  /* unbind the symbol of the name of hashtable in pd's global namespace */
  if (x->x_name != &s_) pd_unbind((t_pd*)x, x->x_name);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_pd: setup()
 */
void pd_gfsm_automaton_pd_setup(void)
{
  //-- class
  pd_gfsm_automaton_pd_class = class_new(gensym("pd_gfsm_automaton_pd"),
					 (t_newmethod)pd_gfsm_automaton_pd_new,
					 (t_method)pd_gfsm_automaton_pd_free,
					 sizeof(t_pd_gfsm_automaton_pd),
					 CLASS_PD,
					 A_DEFSYM,
					 A_NULL);
}

/*=====================================================================
 * Utilities
 *=====================================================================*/

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_pd_find()
 */
t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_find(t_symbol *name)
{
  if (name != &s_)
    return (t_pd_gfsm_automaton_pd*)pd_findbyclass(name,pd_gfsm_automaton_pd_class);
  return NULL;
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_pd_get()
 */
t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_get(t_symbol *name)
{
  t_pd_gfsm_automaton_pd *x = pd_gfsm_automaton_pd_find(name);
  if (!x) {
    x = (t_pd_gfsm_automaton_pd*)pd_gfsm_automaton_pd_new(name);
    x->x_refcnt = 0;
  }
  return x;
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_pd: release()
 */
void pd_gfsm_automaton_pd_release(t_pd_gfsm_automaton_pd *x)
{
  if (x) {
    if (x->x_refcnt) --x->x_refcnt;
    if (!x->x_refcnt) pd_gfsm_automaton_pd_free(x);
  }
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_obj: outlet_symbol()
 */
void pd_gfsm_automaton_obj_outlet_symbol(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *val)
{
  SETSYMBOL(x->x_argv, val);
  outlet_anything(x->x_valout, sel, 1, x->x_argv);
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_obj: outlet_symbol()
 */
void pd_gfsm_automaton_obj_outlet_symbol_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *sym, t_float f)
{
  SETSYMBOL(x->x_argv,  sym);
  SETFLOAT(x->x_argv+1, f);
  outlet_anything(x->x_valout, sel, 2, x->x_argv);
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_obj: outlet_float()
 */
void pd_gfsm_automaton_obj_outlet_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f)
{
  SETFLOAT(x->x_argv, f);
  outlet_anything(x->x_valout, sel, 1, x->x_argv);
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_obj: outlet_float_2()
 */
void pd_gfsm_automaton_obj_outlet_float_2(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f1, t_float f2)
{
  SETFLOAT(x->x_argv  , f1);
  SETFLOAT(x->x_argv+1, f2);
  outlet_anything(x->x_valout, sel, 2, x->x_argv);
}

/*--------------------------------------------------------------------
 * Utilties: pd_gfsm_automaton_obj: outlet_bang()
 */
void pd_gfsm_automaton_obj_outlet_bang(t_pd_gfsm_automaton_obj *x, t_symbol *sel)
{
  SETSYMBOL(x->x_argv, &s_bang);
  outlet_anything(x->x_valout, sel, 1, x->x_argv);
}



/*=====================================================================
 * pd_gfsm_automaton_obj: Methods
 *=====================================================================*/

/*=====================================================================
 * Constructors, etc.
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: new
 */
static void *pd_gfsm_automaton_obj_new(t_symbol *name)
{
  t_pd_gfsm_automaton_obj *x =
    (t_pd_gfsm_automaton_obj *)pd_new(pd_gfsm_automaton_obj_class);

#ifdef PDFSM_DEBUG
  post("pd_gfsm_automaton_obj_new() called: name=%s ; x=%p",
       (name ? name->s_name : "(null)"),
       x);
#endif

    //-- defaults
    //x->x_automaton_pd = NULL;

    //-- bindings
    x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
    x->x_automaton_pd->x_refcnt++;

    //-- outlets
    x->x_valout = outlet_new(&x->x_obj, &s_anything);  //-- value outlet

    return (void *)x;
}


/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: free
 */
static void pd_gfsm_automaton_obj_free(t_pd_gfsm_automaton_obj *x)
{
#ifdef PDFSM_DEBUG
    post("pd_gfsm_automaton_obj_free() called: x=%p", x);
#endif

  pd_gfsm_automaton_pd_release(x->x_automaton_pd);

  //-- do we need to do this?
  outlet_free(x->x_valout);
}

/*=====================================================================
 * automaton_obj: Basic Accessors
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: automaton
 */
static void pd_gfsm_automaton_obj_automaton(t_pd_gfsm_automaton_obj *x, t_symbol *name)
{
  if (name != x->x_automaton_pd->x_name) {
    pd_gfsm_automaton_pd_release(x->x_automaton_pd);
    x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
    ++x->x_automaton_pd->x_refcnt;
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("automaton"), name);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: size()
 */
static void pd_gfsm_automaton_obj_size(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  if (argc > 0) {
    gfsmStateId n = (gfsmStateId)atom_getfloatarg(0,argc,argv);
    gfsm_automaton_reserve(x->x_automaton_pd->x_automaton, n);
  }
  pd_gfsm_automaton_obj_outlet_float
    (x, sel, (t_float)gfsm_automaton_n_states(x->x_automaton_pd->x_automaton));
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: clear()
 */
static void pd_gfsm_automaton_obj_clear(t_pd_gfsm_automaton_obj *x)
{
  gfsm_automaton_clear(x->x_automaton_pd->x_automaton);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("clear"));
}

/*=====================================================================
 * automaton_obj: flags
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: root()
 */
static void pd_gfsm_automaton_obj_root(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  gfsmStateId q0;
  if (argc > 0) {
    q0 = (gfsmStateId)atom_getintarg(0,argc,argv);
    gfsm_automaton_set_root(x->x_automaton_pd->x_automaton, q0);
  } else {
    q0 = gfsm_automaton_get_root(x->x_automaton_pd->x_automaton);
  }

  if (q0==gfsmNoState) pd_gfsm_automaton_obj_outlet_bang(x, sel);
  else                 pd_gfsm_automaton_obj_outlet_float(x, sel, (t_float)q0);
}


/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: weighted()
 */
static void pd_gfsm_automaton_obj_weighted(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  if (argc > 0)
    x->x_automaton_pd->x_automaton->flags.is_weighted = atom_getboolarg(0,argc,argv);
  pd_gfsm_automaton_obj_outlet_float
    (x, sel, (t_float)(x->x_automaton_pd->x_automaton->flags.is_weighted));
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: transducer()
 */
static void pd_gfsm_automaton_obj_transducer(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  if (argc > 0)
    x->x_automaton_pd->x_automaton->flags.is_transducer = atom_getboolarg(0,argc,argv);
  pd_gfsm_automaton_obj_outlet_float
    (x, sel, (t_float)(x->x_automaton_pd->x_automaton->flags.is_transducer));
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: semiring()
 */
static void pd_gfsm_automaton_obj_semiring(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  t_symbol *srsym;
  if (argc > 0) {
    srsym = atom_getsymbolarg(0,argc,argv);
    gfsm_automaton_set_semiring_type(x->x_automaton_pd->x_automaton,
				     gfsm_sr_name_to_type(srsym->s_name));
  }
  srsym = gensym(gfsm_sr_type_to_name(x->x_automaton_pd->x_automaton->sr->type));
  pd_gfsm_automaton_obj_outlet_symbol(x, sel, srsym);
}

/*=====================================================================
 * automaton_obj: state properties
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: final()
 */
static void pd_gfsm_automaton_obj_final(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  gboolean ans = FALSE;
  t_float   qf = atom_getfloatarg(0,argc,argv);
  if (qf<0) qf = -qf;
  if (argc > 1) {
    ans = atom_getboolarg(1,argc,argv);
    gfsm_automaton_set_final_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf, ans);
  } else {
    ans = gfsm_automaton_is_final_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf);
  }
  pd_gfsm_automaton_obj_outlet_float_2(x, sel, qf, (t_float)ans);
}


/*=====================================================================
 * automaton_obj: states & arcs
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: add_state()
 */
static void pd_gfsm_automaton_obj_add_state(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  gfsmStateId id;
  if (argc>0) id = (gfsmStateId)atom_getfloatarg(0,argc,argv);
  else        id = gfsmNoState;

  id = gfsm_automaton_ensure_state(x->x_automaton_pd->x_automaton, id);
  pd_gfsm_automaton_obj_outlet_float(x, sel, (t_float)id);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: add_arc()
 */
static void pd_gfsm_automaton_obj_add_arc(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  t_float qsrc=0, qdst=0;
  t_float clo=0, chi=0;
  t_float w=0;
  if (argc < 2) {
    error("gfsm_automaton: add_arc(): not enough arguments!");
    return;
  }
  switch (argc) {
  case 5: //-- +from, +to, +lo, +hi, +weight
    w = atom_getfloat(argv+4);
  case 4: //-- +from, +to, +lo, +hi, -weight
    chi  = atom_getfloat(argv+3);
  case 3: //-- +from, +to, +lo, -hi, -weight
    clo  = atom_getfloat(argv+2);
  case 2: //-- +from, +to, -lo, -hi, -weight
  default:
    qdst = atom_getfloat(argv+1);
    qsrc = atom_getfloat(argv);

    if (qdst<0) qdst = -qdst;
    if (qsrc<0) qsrc = -qsrc;
    break;
  }

  gfsm_automaton_add_arc(x->x_automaton_pd->x_automaton,
			 (gfsmStateId)qsrc,
			 (gfsmStateId)qdst,
			 (gfsmLabelId)clo,
			 (gfsmLabelId)chi,
			 (gfsmWeight)w);

#ifdef PDFSM_DEBUG
  post("pd_gfsm_automaton_obj_add_arc(): node(qsrc=%ld).out_degree=%u",
       qsrc,
       gfsm_automaton_out_degree(x->x_automaton_pd->x_automaton, qsrc));
#endif

  //-- output
  SETFLOAT(x->x_argv  , (t_float)qsrc);
  SETFLOAT(x->x_argv+1, (t_float)qdst);
  SETFLOAT(x->x_argv+2, (t_float)clo);
  SETFLOAT(x->x_argv+3, (t_float)chi);
  SETFLOAT(x->x_argv+4, (t_float)w);
  outlet_anything(x->x_valout, sel, 5, x->x_argv);
}

/*=====================================================================
 * automaton_obj: Text I/O
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: print()
 */
static void pd_gfsm_automaton_obj_print(t_pd_gfsm_automaton_obj *x)
{
  gfsmError *errp = NULL;
  gfsmIOHandle *ioh  = pd_gfsm_console_handle_new();
  gfsm_automaton_print_handle(x->x_automaton_pd->x_automaton,
			      ioh, NULL,NULL,NULL, &errp);
  if (errp) {
    error("gfsm_automaton: print(): Error: %s\n", errp->message);
    g_error_free(errp);
  }
  pd_gfsm_console_handle_free(ioh);
  pd_gfsm_automaton_obj_outlet_bang(x, gensym("print"));
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: load_txt()
 */
static void pd_gfsm_automaton_obj_load_txt(t_pd_gfsm_automaton_obj *x, t_symbol *s)
{
  gfsmError *errp = NULL;
  gfsm_automaton_compile_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
  if (errp) {
    error("gfsm_automaton: load_txt(%s): Error: %s\n", s->s_name, errp->message);
    g_error_free(errp);
  } 
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("load"), s);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: save_txt()
 */
static void pd_gfsm_automaton_obj_save_txt(t_pd_gfsm_automaton_obj *x, t_symbol *s)
{
  gfsmError *errp = NULL;
  gfsm_automaton_print_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
  if (errp) {
    error("gfsm_automaton: save_txt(%s): Error: %s\n", s->s_name, errp->message);
    g_error_free(errp);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("save"), s);
}


/*=====================================================================
 * automaton_obj: Binary I/O
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: load_bin()
 */
static void pd_gfsm_automaton_obj_load_bin(t_pd_gfsm_automaton_obj *x, t_symbol *s)
{
  gfsmError *errp = NULL;
  gfsm_automaton_load_bin_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
  if (errp) {
    error("gfsm_automaton: load_bin(%s): Error: %s\n", s->s_name, errp->message);
    g_error_free(errp);
  }
  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("load_bin"), s);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: save_bin()
 */
static void pd_gfsm_automaton_obj_save_bin(t_pd_gfsm_automaton_obj *x, t_symbol *s, t_float zlevel)
{
  gfsmError *errp = NULL;
  gfsm_automaton_save_bin_filename(x->x_automaton_pd->x_automaton, s->s_name, (int)zlevel, &errp);
  if (errp) {
    error("gfsm_automaton: save_bin(%s,%d): Error: %s\n", s->s_name, (int)zlevel, errp->message);
    g_error_free(errp);
  }
  pd_gfsm_automaton_obj_outlet_symbol_float(x, gensym("save_bin"), s, (int)zlevel);
}


/*=====================================================================
 * automaton_obj: info
 */

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: info()
 */
static void pd_gfsm_automaton_obj_info(t_pd_gfsm_automaton_obj *x)
{
  gfsmAutomaton *fsm = x->x_automaton_pd->x_automaton;
  guint n_eps_i, n_eps_o, n_eps_io;

#define bool2char(b) ((b) ? 'y' : 'n')

  post("-- GFSM Automaton Info --");
  post("%-24s: %s", "Name", x->x_automaton_pd->x_name->s_name);
  post("%-24s: %s", "Semiring", gfsm_sr_type_to_name(fsm->sr->type));
  post("%-24s: %c", "Transducer?", bool2char(gfsm_automaton_is_transducer(fsm)));
  post("%-24s: %c", "Weighted?", bool2char(gfsm_automaton_is_weighted(fsm)));
  post("%-24s: %c", "Deterministic?", bool2char(fsm->flags.is_deterministic));
  post("%-24s: %s", "Sort Mode", gfsm_arc_sortmode_to_name(gfsm_automaton_sortmode(fsm)));
  if (fsm->root_id == gfsmNoState)
    post("%-24s: %s", "Initial state", "(none)");
  else 
    post("%-24s: %u", "Initial state", fsm->root_id);
  post("%-24s: %u", "# of states", gfsm_automaton_n_states(fsm));
  post("%-24s: %u", "# of final states", gfsm_automaton_n_final_states(fsm));
  post("%-24s: %u", "# of arcs", gfsm_automaton_n_arcs_full(fsm, &n_eps_i, &n_eps_o, &n_eps_io));
  post("%-24s: %u", "# of i/o epsilon arcs", n_eps_io);
  post("%-24s: %u", "# of input epsilon arcs", n_eps_i);
  post("%-24s: %u", "# of output epsilon arcs", n_eps_o);
  post("%-24s: %c", "cyclic?", bool2char(gfsm_automaton_is_cyclic(fsm)));
  //...

#undef bool2char

  pd_gfsm_automaton_obj_outlet_bang(x, gensym("info"));
}


/*=====================================================================
 * automaton_obj: draw
 */

/*--------------------------------------------------------------------
 * automaton_obj: draw_dot()
 */
static void pd_gfsm_automaton_obj_draw_dot(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
{
  t_pd_gfsm_alphabet_pd *ialph=NULL, *oalph=NULL, *salph=NULL;
  t_symbol
    *filename = atom_getsymbolarg(0,argc,argv),
    *title    = x->x_automaton_pd->x_name,
    *fontname = NULL;
  float
    width=0,
    height=0,
    nodesep=0,
    ranksep=0;
  int fontsize=0;
  gboolean
    portrait=FALSE,
    vertical=FALSE;
  gfsmError *errp = NULL;
  int i;

  for (i=1; i < argc; i++) {
    t_symbol *opt = atom_getsymbolarg(i,argc,argv);

    //--debug
    //post("gfsm_automaton: draw_dot: checking option '%s'", opt->s_name);

    if (opt==gensym("ilabels")) {
      if (ialph) pd_gfsm_alphabet_pd_release(ialph);
      ialph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
      if (ialph) ialph->x_refcnt++;
    }
    else if (opt==gensym("olabels")) {
      if (oalph) pd_gfsm_alphabet_pd_release(oalph);
      oalph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
      if (oalph) oalph->x_refcnt++;
    }
    else if (opt==gensym("slabels")) {
      if (salph) pd_gfsm_alphabet_pd_release(salph);
      salph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
      if (salph) salph->x_refcnt++;
    }
    else if (opt==gensym("title")) title = atom_getsymbolarg(++i,argc,argv);
    else if (opt==gensym("width")) width = atom_getfloatarg(++i,argc,argv);
    else if (opt==gensym("height")) height = atom_getfloatarg(++i,argc,argv);
    else if (opt==gensym("fontsize")) fontsize = atom_getintarg(++i,argc,argv);
    else if (opt==gensym("fontname")) fontname = atom_getsymbolarg(++i,argc,argv);
    else if (opt==gensym("portrait")) portrait = atom_getboolarg(++i,argc,argv);
    else if (opt==gensym("vertical")) vertical = atom_getboolarg(++i,argc,argv);
    else if (opt==gensym("nodesep")) nodesep = atom_getfloatarg(++i,argc,argv);
    else if (opt==gensym("ranksep")) ranksep = atom_getfloatarg(++i,argc,argv);
    else {
      char buf[64];
      atom_string(argv+i, buf, 64);
      error("gfsm_automaton: draw_dot: unknown option '%s' ignored", buf);
    }
  }

  gfsm_automaton_draw_dot_filename_full(x->x_automaton_pd->x_automaton,
					filename->s_name,
					(ialph ? ialph->x_alphabet : NULL),
					(oalph ? oalph->x_alphabet : NULL),
					(salph ? salph->x_alphabet : NULL),
					title->s_name,
					width,
					height,
					fontsize,
					(fontname ? fontname->s_name : NULL),
					portrait,
					vertical,
					nodesep,
					ranksep,
					&errp);
  
  if (errp) {
    error("gfsm_automaton: draw_dot(%s): Error: %s\n", filename->s_name, errp->message);
    g_error_free(errp);
  }

  //-- cleanup
  if (ialph) pd_gfsm_alphabet_pd_release(ialph);
  if (oalph) pd_gfsm_alphabet_pd_release(oalph);
  if (salph) pd_gfsm_alphabet_pd_release(salph);

  pd_gfsm_automaton_obj_outlet_symbol(x, gensym("draw_dot"), filename);
}

/*--------------------------------------------------------------------
 * pd_gfsm_automaton_obj: setup()
 */
static void pd_gfsm_automaton_obj_setup(void)
{
  //-- class
  pd_gfsm_automaton_obj_class = class_new(gensym("gfsm_automaton"),
					  (t_newmethod)pd_gfsm_automaton_obj_new,
					  (t_method)pd_gfsm_automaton_obj_free,
					  sizeof(t_pd_gfsm_automaton_obj),
					  CLASS_DEFAULT,
					  A_DEFSYM,
					  A_NULL);

  //-- methods: automaton
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_automaton,
		  gensym("automaton"),
		  A_DEFSYM, A_NULL);

  //-- methods: flags
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_root,
		  gensym("root"),
		  A_GIMME, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_weighted,
		  gensym("weighted"),
		  A_GIMME, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_transducer,
		  gensym("transducer"),
		  A_GIMME, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_semiring,
		  gensym("semiring"),
		  A_GIMME, A_NULL);
  
  //-- methods: size
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_size,
		  gensym("size"),
		  A_GIMME, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_clear,
		  gensym("clear"),
		  A_NULL);

  //-- methods: state properties
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_final,
		  gensym("final"),
		  A_GIMME, A_NULL);

  //-- methods: states & arcs
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_add_state,
		  gensym("add_state"),
		  A_GIMME, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_add_arc,
		  gensym("add_arc"),
		  A_GIMME,  //-- qsrc,qdst,clo,chi,weight
		  A_NULL);


  //-- methods: I/O: text
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_print,
		  gensym("print"),
		  A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_load_txt,
		  gensym("load"),
		  A_SYMBOL, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_save_txt,
		  gensym("save"),
		  A_SYMBOL, A_NULL);

  //-- methods: I/O: binary
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_load_bin,
		  gensym("load_bin"),
		  A_SYMBOL, A_NULL);
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_save_bin,
		  gensym("save_bin"),
		  A_SYMBOL, A_DEFFLOAT, A_NULL);

  //-- methods: info
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_info,
		  gensym("info"),
		  A_NULL);

  //-- methods: draw
  class_addmethod(pd_gfsm_automaton_obj_class,
		  (t_method)pd_gfsm_automaton_obj_draw_dot,
		  gensym("draw_dot"),
		  A_GIMME, A_NULL);

  //-- help symbol
  class_sethelpsymbol(pd_gfsm_automaton_obj_class, gensym("gfsm_automaton-help.pd"));
}


/*=====================================================================
 * automaton setup
 *=====================================================================*/

/*--------------------------------------------------------------------
 * pd_gfsm_automaton: setup()
 */
void pd_gfsm_automaton_setup(void)
{
  pd_gfsm_automaton_pd_setup();
  pd_gfsm_automaton_obj_setup();
  pd_gfsm_algebra_setup(pd_gfsm_automaton_obj_class);
}

--- NEW FILE: pd_state.h ---
/*=============================================================================*\
 * File: pd_state.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

/*=====================================================================
 * Protos
 *=====================================================================*/
#ifndef PD_GFSM_STATE_H
#define PD_GFSM_STATE_H

/*----------------------------------------------------------------------
 * includes
 */
#include <pd_automaton.h>

/*--------------------------------------------------------------
 * pd_fsm_automaton_pd
 */
typedef struct _pd_gfsm_state
{
  t_object                 x_obj;
  t_pd_gfsm_automaton_pd  *x_automaton_pd;
  gfsmStateId              x_id;
  gfsmArcIter              x_arci;
  gboolean                 x_open;
  t_atom                   x_argv[4];
  t_outlet                *x_valout;
} t_pd_gfsm_state;

/*----------------------------------------------------------------------
 * setup routines
 */
void pd_gfsm_state_setup(void);

#endif /* PD_GFSM_STATE_H */

--- NEW FILE: gfsm_state-help.pd ---
#N canvas 232 0 651 599 10;
#X obj 85 569 gfsm;
#X text 15 569 SEE ALSO:;
#X text 41 6 gfsm_state : position "pointer" for finite-state automata
;
#X text 267 563 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X text 17 79 INLETS:;
#X text 35 93 1 - control messages;
#X text 255 82 OUTLETS:;
#X text 271 95 1 - value outlet;
#X text 18 30 SYNTAX: gfsm_state [FSM_NAME [STATE_ID]];
#X text 52 47 FSM_NAME - symbolic name of a gfsm_automaton;
#X text 52 61 STATE_ID - numeric Id of the target state;
#X obj 26 531 print gfsm-state-out;
#X msg 44 182 id;
#X text 164 185 "id" : get current state Id;
#X text 135 205 "set ID" : set current state Id;
#X msg 50 205 set 0;
#X msg 26 127 automaton;
#X msg 31 149 automaton fsm-help;
#X text 197 128 "automaton" : use an object-local machine;
#X text 163 151 "automaton NAME" : use a shared machine named NAME
;
#X msg 58 239 degree;
#X text 137 240 "degree" : get number of outgoing arcs (linear time)
;
#X msg 58 295 arc_first;
#X msg 58 317 arc_next;
#X msg 59 382 arc_reset;
#X obj 26 508 gfsm_state fsm-help 0;
#X text 229 398 arcs are output as a list:;
#X text 277 414 NEXT_STATEID LO HI WEIGHT;
#X text 306 359 (negative labels are ignored);
#X msg 58 345 arc_seek 202 -1;
#X text 208 294 "arc_first" : get first outgoing arc;
#X text 214 318 "arc_next" : get next available outgoing arc (maybe
first);
#X text 173 344 "arc_seek LO HI" : get next arc with labels LO:HI;
#X text 207 383 "arc_reset" : close internal arc iterator;
#X msg 54 447 add_weight 1 -1 101 0.9;
#X text 233 450 "add_weight ID LO HI W" : add W to 1st arc to state
ID;
#X text 416 463 with labels LO:HI;
#X text 271 479 (implicitly resets arc iterator);
#X connect 12 0 25 0;
#X connect 15 0 25 0;
#X connect 16 0 25 0;
#X connect 17 0 25 0;
#X connect 20 0 25 0;
#X connect 22 0 25 0;
#X connect 23 0 25 0;
#X connect 24 0 25 0;
#X connect 25 0 11 0;
#X connect 29 0 25 0;
#X connect 34 0 25 0;

--- NEW FILE: atom_alphabet.h ---
/*=============================================================================*\
 * File: atom_alphabet.h
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd: atom alphabet
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#ifndef _PD_GFSM_ATOM_ALPHABET_H
#define _PD_GFSM_ATOM_ALPHABET_H

#include <m_pd.h>
#include <gfsm.h>

/*--------------------------------------------------------------
 * Constants
 */
#define PdGfsmStrBufSize 256

extern gfsmUserAlphabetMethods pd_atom_alphabet_methods;

/*--------------------------------------------------------------
 * Types: gfsmPdAtomAlphabet
 */
typedef struct {
  gfsmUserAlphabet  aa_alph;
  t_binbuf         *aa_binbuf;
  char              aa_strbuf[PdGfsmStrBufSize];
} gfsmPdAtomAlphabet;

/*--------------------------------------------------------------
 * gfsmPdAtomAlphabet: user methods
 */
//-- hash function for pd atoms
guint gfsm_pd_atom_hash(t_atom *a);

//-- equality check for pd atoms
gboolean gfsm_pd_atom_equal(t_atom *a1, t_atom *a2);

//-- dup function for pd atoms
t_atom *gfsm_pd_atom_dup(gfsmPdAtomAlphabet *alph, t_atom *a);

//-- free function for pd atoms
void gfsm_pd_atom_free(t_atom *a);

//-- string read function for pd atoms
t_atom *gfsm_pd_atom_read(gfsmPdAtomAlphabet *alph, GString *gstr);

//-- string write function for pd atoms
void gfsm_pd_atom_write(gfsmPdAtomAlphabet *alph, t_atom *a, GString *gstr);

/*--------------------------------------------------------------
 * gfsmPdAtomAlphabet: utilities
 */
//-- constructor
gfsmPdAtomAlphabet *gfsm_pd_atom_alphabet_new(void);

//-- destructor
void gfsm_pd_atom_alphabet_free(gfsmPdAtomAlphabet *alph);

#endif /* _PD_GFSM_ATOM_ALPHABET_H */

--- NEW FILE: gfsm_automaton-help.pd ---
#N canvas 126 0 473 476 10;
#X text 89 7 gfsm_automaton : weighted finite state machine;
#X text 173 441 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X text 7 379 SEE ALSO:;
#X obj 22 399 gfsm;
#X text 12 73 INLETS:;
#X text 30 87 1 - control messages;
#X text 244 74 OUTLETS:;
#X text 260 87 1 - value outlet;
#X text 48 48 NAME - symbolic name of the machine;
#X text 14 31 SYNTAX: gfsm_automaton [NAME];
#X text 7 211 SUBTOPICS:;
#X text 10 114 DESCRIPTION:;
#X text 245 211 GUTS:;
#X text 28 130 gfsm_automaton objects represent weighted finite state
machines (acceptors or transducers) -- rooted \, acyclic graphs whose
edges are labelled with triples (LO \, HI \, WEIGHT) \, where LO and
HI are alphabet labels (see gfsm_alphabet) \, and WEIGHT is a floating
point number.;
#X obj 265 272 print fsm-help-out;
#X obj 137 400 gfsm_alphabet;
#N canvas 192 14 651 458 help-automaton-flags 0;
#X text 167 4 gfsm_automaton : flags;
#X msg 22 36 weighted;
#X msg 32 171 transducer 1;
#X msg 33 192 transducer 0;
#X msg 22 151 transducer;
#X msg 33 57 weighted 1;
#X msg 34 78 weighted 0;
#X msg 24 275 semiring;
#X msg 37 299 semiring boolean;
#X msg 37 320 semiring log;
#X msg 37 361 semiring real;
#X msg 37 382 semiring trivial;
#X msg 38 402 semiring tropical;
#X text 192 35 "weighted" : get value of the boolean "weighted" flag
;
#X text 157 57 "weighted BOOL" : set "weighted" flag;
#X text 214 87 weighted automata may behave differently than unweighted
automata with respect to certain algebraic operations.;
#X text 178 148 "transducer" : get value of the boolean "transducer"
flag;
#X text 143 170 "transducer BOOL" : set "transducer" flag;
#X text 216 195 transducers may behave differently than acceptors (which
have only one label per arc) with respect to certain algebraic operations.
;
#X text 157 297 "semiring TYPE" : set semiring to use for weight arithmetic
;
#X text 192 272 "semiring" : get semiring type used for weight arithmetic
;
#X text 336 434 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X text 218 328 algebraic operations may be called on to alter arc
weights \; in this case \, the semiring type associated with the automaton
will be used to interpret arc weights. work in progress -- if you need
this for something \, let me know.;
#X obj 22 101 s fsm-help-in;
#X obj 22 216 s fsm-help-in;
#X obj 24 428 s fsm-help-in;
#X msg 37 341 semiring plog;
#X connect 1 0 23 0;
#X connect 2 0 24 0;
#X connect 3 0 24 0;
#X connect 4 0 24 0;
#X connect 5 0 23 0;
#X connect 6 0 23 0;
#X connect 7 0 25 0;
#X connect 8 0 25 0;
#X connect 9 0 25 0;
#X connect 10 0 25 0;
#X connect 11 0 25 0;
#X connect 12 0 25 0;
#X connect 26 0 25 0;
#X restore 19 230 pd help-automaton-flags;
#N canvas 71 31 651 409 help-automaton-basic 0;
#X text 345 383 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X obj 21 119 s fsm-help-in;
#X text 167 4 gfsm_automaton : basic operations;
#X msg 21 45 automaton;
#X msg 28 69 automaton fsm-help-2;
#X msg 29 91 automaton fsm-help;
#X text 179 38 "automaton" : use an object-local machine;
#X text 145 51 "automaton NAME" : use a shared machine named NAME;
#X msg 29 193 clear;
#X text 124 192 "clear" : clears the automaton;
#X msg 34 217 info;
#X text 130 215 "info" : prints summary information to the Pd console
;
#X msg 35 241 print;
#X text 221 74 data is shared between automata of the same name. when
using multiple shared automata \, take care always to leave at least
one object "pointing" to each name \, since the underlying data structures
are freed when all references are lost.;
#X text 124 236 "print" : prints automaton in at&t text format to stdout
;
#X obj 19 269 s fsm-help-in;
#X text 145 262 WARNING: these methods may hog the cpu for extended
periods of time when called for large machines.;
#X msg 22 169 renumber;
#X text 102 170 "renumber" : renumber automaton states \, closing gaps
;
#X connect 3 0 1 0;
#X connect 4 0 1 0;
#X connect 5 0 1 0;
#X connect 8 0 15 0;
#X connect 10 0 15 0;
#X connect 12 0 15 0;
#X connect 17 0 15 0;
#X restore 19 252 pd help-automaton-basic;
#N canvas 27 14 658 321 help-automaton-io 0;
#X text 101 2 gfsm_automaton : input/output;
#X obj 13 93 s fsm-help-in;
#X text 211 44 "load FILE" : load an automaton in at&t-style text format
;
#X text 212 68 "save FILE" : save automaton in at&t-style text format
;
#X obj 10 235 s fsm-help-in;
#X text 225 160 "load_bin FILE" : load an automaton in GFSM binary
format;
#X text 354 292 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X msg 23 48 load gfsm-help.tfst;
#X msg 17 162 load_bin gfsm-help.gfst;
#X msg 23 69 save gfsm-help.tfst;
#X text 243 240 NOTE: gfsm binary format is not portable across different
architectures.;
#X text 235 87 NOTE: currently \, all text i/o is done in "weighted
transducer" format \, regardless of automaton flags or input file content.
;
#X text 227 184 "save_bin FILE" : save automaton in GFSM binary format
;
#X msg 18 184 save_bin gfsm-help.gfst;
#X text 228 209 "save_bin FILE ZLEVEL" : save with zlib compression
;
#X msg 24 208 save_bin gfsm-help.gfst 9;
#X connect 7 0 1 0;
#X connect 8 0 4 0;
#X connect 9 0 1 0;
#X connect 13 0 4 0;
#X connect 15 0 4 0;
#X restore 21 296 pd help-automaton-io;
#N canvas 199 1 636 611 help-automaton-algebra 0;
#X msg 24 33 complement;
#X msg 24 62 closure 0;
#X msg 24 79 closure 1;
#X msg 24 170 determinize;
#X msg 24 201 difference fsm-help-2;
#X msg 24 235 intersect fsm-help-2;
#X msg 24 267 invert;
#X msg 24 352 product fsm-help-2;
#X msg 24 413 reverse;
#X msg 24 444 rmepsilon;
#X msg 24 479 union fsm-help-2;
#X text 222 32 "complement" : compute complement of an acceptor;
#X msg 24 140 concat fsm-help;
#X text 215 141 "concat FSM2" : concatenate with automaton named FSM2
;
#X text 187 197 "difference FSM2" : remove language of automaton named
FSM2;
#X text 194 228 "intersect FSM2" : intersect with automaton named FSM2
;
#X text 250 266 "invert" : swap upper and lower labels;
#X msg 24 302 project 0;
#X msg 24 319 project 1;
#X text 208 298 "project SIDE" : project one label side;
#X text 327 311 SIDE=0: project lower labels;
#X text 328 323 SIDE=1: project upper labels;
#X text 208 348 "product FSM2" : compute Cartesian product with FSM2
;
#X text 243 407 "reverse" : reverse language of an automaton;
#X text 95 6 gfsm_automaton : algebraic operations;
#X text 229 439 "rmepsilon" : remove epsilon arcs;
#X text 222 478 "union FSM2" : compute union with automaton FSM2;
#X obj 24 505 s fsm-help-in;
#X text 31 551 WARNING: these methods may block for long periods of
time for large automata.;
#X text 329 578 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X msg 24 109 compose fsm-help-2;
#X text 208 109 "compose FSM2" : compose with transducer FSM2;
#X text 229 70 "closure N" : compute N-ary closure;
#X text 215 170 "determinize" : determinize an acceptor;
#X msg 24 383 connect;
#X text 244 382 "connect" : remove useless states and arcs;
#X connect 0 0 27 0;
#X connect 1 0 27 0;
#X connect 2 0 27 0;
#X connect 3 0 27 0;
#X connect 4 0 27 0;
#X connect 5 0 27 0;
#X connect 6 0 27 0;
#X connect 7 0 27 0;
#X connect 8 0 27 0;
#X connect 9 0 27 0;
#X connect 10 0 27 0;
#X connect 12 0 27 0;
#X connect 17 0 27 0;
#X connect 18 0 27 0;
#X connect 30 0 27 0;
#X connect 34 0 27 0;
#X restore 21 342 pd help-automaton-algebra;
#X obj 59 400 gfsm_state;
#X obj 265 230 r fsm-help-in;
#N canvas 293 117 651 504 help-automaton-access 0;
#X msg 22 42 size;
#X floatatom 33 66 5 0 0 0 - - -;
#X msg 33 82 size \$1;
#X obj 22 104 s fsm-help-in;
#X text 118 38 "size" : get number of states in the machine;
#X text 90 51 "size INT" : grow machine to at least INT states;
#X text 99 5 gfsm_automaton : automaton access;
#X floatatom 35 177 5 0 0 0 - - -;
#X obj 24 215 s fsm-help-in;
#X msg 24 153 root;
#X msg 35 193 root \$1;
#X text 120 149 "root" : get id of machine's initial state or "bang"
;
#X text 134 72 note that values reported do not take the VALIDITY of
states into account -- your mileage may vary.;
#X text 132 180 in the second form \, the state will be created if
it does not already exist. states are internally stored in an array
\, and indexed with positive integer IDs beginning from 0 (zero) --
i.e. \, a message such as "root 1E+37" is likely to crash Pd.;
#X text 99 162 "root ID" : set machine's initial state to ID (an integer)
;
#X text 139 273 "final ID" : check whether state ID is marked as final
;
#X text 104 297 "final ID BOOL" : set final-status of state ID to BOOL
;
#X obj 23 344 s fsm-help-in;
#X text 143 314 same caveats as for "root";
#X obj 26 436 s fsm-help-in;
#X msg 23 276 final 1;
#X msg 30 299 final 1 1;
#X msg 31 319 final 1 0;
#X text 207 388 "add_arc FROM TO LO HI WEIGHT" : add an arc;
#X text 242 403 adds an arc from state FROM to state TO on lower (input)
label LO and upper (output) label HI with weight WEIGHT. states FROM
and TO are implicitly created.;
#X msg 26 390 add_arc 0 1 2 3 4;
#X msg 38 412 add_arc 0 2 42 24 0.7;
#X text 349 480 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X connect 0 0 3 0;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X connect 7 0 10 0;
#X connect 9 0 8 0;
#X connect 10 0 8 0;
#X connect 20 0 17 0;
#X connect 21 0 17 0;
#X connect 22 0 17 0;
#X connect 25 0 19 0;
#X connect 26 0 19 0;
#X restore 20 274 pd help-automaton-access;
#N canvas 15 0 687 348 help-automaton-draw 0;
#X obj 13 256 s fsm-help-in;
#X text 246 63 NOTE: interpreting the resulting file requires the 'graphviz'
package from at&t.;
#X text 225 39 "draw_dot FILE [OPTIONS]" : save a 'dot' graph specification
;
#X text 235 97 OPTIONS:;
#X text 318 113 title TITLE : graph title;
#X text 318 168 width WIDTH : graph width (inches);
#X text 248 127 ilabels ALPHABET_NAME : lower-label alphabet name;
#X text 248 140 olabels ALPHABET_NAME : upper-label alphabet name;
#X text 248 154 slabels ALPHABET_NAME : state-label alphabet name;
#X text 304 180 height HEIGHT : graph height (inches);
#X text 304 193 fontsize SIZE : font size (points?);
#X text 304 206 fontname NAME : font name (?);
#X text 304 219 portrait BOOL : draw in portrait mode? (default=no)
;
#X text 304 231 vertical BOOL : draw top-to-bottom? (default=no);
#X text 297 244 nodesep INCHES : node-separation distance;
#X text 297 257 ranksep INCHES : rank-separation distance;
#X text 115 9 gfsm_automaton : draw;
#X text 370 326 Bryan Jurish <moocow at ling.uni-potsdam.de>;
#X msg 13 40 draw_dot fsm-help.dot;
#X obj 14 311 shell;
#X msg 14 291 dotty fsm-help.dot;
#X text 235 291 ... try this if you have the "graphviz" package installed
;
#X connect 18 0 0 0;
#X connect 20 0 19 0;
#X restore 20 318 pd help-automaton-draw;
#X text 239 401 gfsmutils(1);
#X obj 265 344 gfsm_automaton fsm-help-2;
#X text 248 303 PLACEHOLDERS:;
#X obj 265 323 gfsm_automaton fsm-help;
#X obj 265 251 gfsm_automaton fsm-help;
#X connect 21 0 28 0;
#X connect 28 0 14 0;

--- NEW FILE: atom_alphabet.c ---
/*=============================================================================*\
 * File: atom_alphabet.c
 * Author: Bryan Jurish <moocow at ling.uni-potsdam.de>
 * Description: finite state automata for Pd: atom alphabet
 *
 * Copyright (c) 2004 Bryan Jurish.
 *
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * See file LICENSE for further informations on licensing terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *=============================================================================*/

#include <atom_alphabet.h>
#include <string.h>

/*======================================================================
 * constants
 */
gfsmUserAlphabetMethods pd_atom_alphabet_methods =
  {
    NULL, //-- key->label lookup function
    NULL, //-- label->key lookup function
    NULL, //-- insertion function: receives a newly copied key!
    NULL, //-- label removal function
    (gfsmAlphabetKeyReadFunc)gfsm_pd_atom_read,   //-- key input function
    (gfsmAlphabetKeyWriteFunc)gfsm_pd_atom_write  //-- key output function
  };

/*======================================================================
 * gfsmPdAtomAlphabet: user methods
 */


/*--------------------------------------------------------------
 * hash()
 */
guint gfsm_pd_atom_hash(t_atom *a)
{
  if (!a) return 0;
  switch (a->a_type) {
  case A_FLOAT:  return (guint)(a->a_w.w_float);
  case A_SYMBOL: return (guint)(a->a_w.w_symbol);
  case A_SEMI:   return (guint)';';
  case A_COMMA:  return (guint)',';
  default:       return 0;
  }
  return 0; //-- never reached
}

/*--------------------------------------------------------------
 * equal()
 */
gboolean gfsm_pd_atom_equal(t_atom *a1, t_atom *a2)
{
  if (a1->a_type != a2->a_type) return FALSE;
  switch (a1->a_type) {
  case A_FLOAT:  return a1->a_w.w_float == a2->a_w.w_float;
  case A_SYMBOL: return a1->a_w.w_symbol == a2->a_w.w_symbol;
  default:       return memcmp(a1,a2,sizeof(t_atom))==0;
  }
}

/*--------------------------------------------------------------
 * dup()
 */
t_atom *gfsm_pd_atom_dup(gfsmPdAtomAlphabet *alph, t_atom *a)
{
  //return (a ? copybytes(a, sizeof(t_atom)) : NULL);
  return (a ? gfsm_mem_dup_n(a,sizeof(t_atom)) : NULL);
}

/*--------------------------------------------------------------
 * free()
 */
void gfsm_pd_atom_free(t_atom *a)
{ g_free(a); }

/*--------------------------------------------------------------
 * read()
 */
t_atom *gfsm_pd_atom_read(gfsmPdAtomAlphabet *alph, GString *gstr)
{
  binbuf_clear(alph->aa_binbuf);
  binbuf_text(alph->aa_binbuf, gstr->str, gstr->len);
  return binbuf_getvec(alph->aa_binbuf);
}

/*--------------------------------------------------------------
 * write()
 */
void gfsm_pd_atom_write(gfsmPdAtomAlphabet *alph, t_atom *a, GString *gstr)
{
  atom_string(a, alph->aa_strbuf, PdGfsmStrBufSize);
  g_string_assign(gstr, alph->aa_strbuf);
}

/*======================================================================
 * gfsmPdAtomAlphabet: shortcuts
 */

/*--------------------------------------------------------------
 * new
 */
gfsmPdAtomAlphabet *gfsm_pd_atom_alphabet_new(void)
{
  gfsmPdAtomAlphabet *alph = g_new0(gfsmPdAtomAlphabet,1);
  ((gfsmAlphabet*)alph)->type = gfsmATUser;
  gfsm_user_alphabet_init((gfsmUserAlphabet*)alph,
			  (gfsmAlphabetKeyDupFunc)gfsm_pd_atom_dup,
			  (GHashFunc)gfsm_pd_atom_hash,
			  (GEqualFunc)gfsm_pd_atom_equal,
			  (GDestroyNotify)gfsm_pd_atom_free,
			  NULL,
			  &pd_atom_alphabet_methods);
  alph->aa_binbuf = binbuf_new();
  return alph;
}

//-- destructor
void gfsm_pd_atom_alphabet_free(gfsmPdAtomAlphabet *alph)
{
  if (alph->aa_binbuf) binbuf_free(alph->aa_binbuf);
  gfsm_alphabet_free((gfsmAlphabet*)alph);
}

--- NEW FILE: test-fsm.pd ---
#N canvas 0 0 450 300 10;
#X obj 166 146 fsm;

--- NEW FILE: test-automaton2.pd ---
#N canvas 110 261 845 398 10;
#X obj 13 7 gfsm;
#X obj 23 362 print GFSM-1;
#X obj 116 362 print GFSM-2;
#X obj 208 363 print GFSM-3;
#X msg 26 70 automaton;
#X msg 24 29 automaton a1;
#X obj 16 91 s \$0-fsm;
#X obj 93 294 r \$0-fsm;
#X msg 153 75 size;
#X floatatom 237 34 5 0 0 0 - - -;
#X obj 237 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 237 51 set_root \$1;
#X msg 246 74 get_root;
#X msg 144 52 reserve \$1;
#X floatatom 144 34 5 0 0 0 - - -;
#X msg 257 15 0;
#X msg 145 13 42;
#X msg 349 37 is_final \$1;
#X floatatom 375 18 5 0 0 0 - - -;
#X msg 347 17 0;
#X floatatom 388 61 5 0 0 0 - - -;
#X msg 360 60 0;
#X msg 363 80 set_final \$1 1;
#X floatatom 517 34 5 0 0 0 - - -;
#X floatatom 560 33 5 0 0 0 - - -;
#X floatatom 603 33 5 0 0 0 - - -;
#X floatatom 644 34 5 0 0 0 - - -;
#X obj 543 59 pack 0 0 0 0 0;
#X obj 494 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X obj 494 57 t b b;
#X msg 569 7 0;
#X msg 495 105 add_arc \$1 \$2 \$3 \$4 \$5;
#X obj 144 98 s \$0-fsm;
#X obj 237 97 s \$0-fsm;
#X obj 349 102 s \$0-fsm;
#X obj 496 126 s \$0-fsm;
#X msg 104 148 load test.tfst;
#X msg 103 188 save tmp.tfst;
#X msg 229 148 load_bin test.gfst;
#X msg 234 232 save_bin tmp.gfst;
#X msg 26 202 print;
#X msg 22 179 clear;
#X msg 18 158 info;
#X obj 16 224 s \$0-fsm;
#X obj 95 209 s \$0-fsm;
#X obj 228 254 s \$0-fsm;
#X msg 437 170 complement;
#X msg 450 211 closure \$1;
#X floatatom 466 193 5 0 0 0 - - -;
#X obj 437 370 s \$0-fsm;
#X obj 16 132 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
-1 -1;
#X obj 450 193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 457 236 compose a2;
#X msg 462 264 concat a2;
#X obj 51 6 zexy;
#X obj 495 84 lister;
#X msg 25 48 automaton a2;
#X msg 464 291 determinize;
#X msg 469 319 difference a2;
#X msg 475 343 intersect a2;
#X obj 603 368 s \$0-fsm;
#X msg 603 165 invert;
#X msg 612 191 product a2;
#X msg 626 234 project \$1;
#X floatatom 643 213 5 0 0 0 - - -;
#X obj 624 215 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 631 262 prune;
#X msg 636 286 reverse;
#X msg 636 313 rmepsilon;
#X msg 639 337 union a2;
#X msg 103 168 load test2.tfst;
#X msg 233 169 load_bin test2.gfst;
#X obj 92 318 gfsm_automaton a2;
#X msg 238 190 load_bin test3.gfst;
#X floatatom 626 5 5 0 0 0 - - -;
#N canvas 0 0 466 454 draw 0;
#X obj 67 25 r \$0-draw-s;
#X obj 68 68 f \$0;
#X msg 176 74 save_bin \$1draw.gfst;
#X obj 176 98 s \$0-fsm;
#X obj 68 162 shell;
#X obj 68 47 t b;
#X obj 68 91 t f f;
#X msg 69 237 dotgv.sh \$1draw.dot;
#X obj 171 311 f \$0;
#X obj 172 291 t b;
#X obj 171 357 shell;
#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
#X obj 142 270 shell;
#X msg 220 236 dotty \$1draw.dot;
#X obj 169 183 r \$0-drawmode-s;
#X obj 111 206 demux 0 1;
#X obj 110 163 t b;
#X obj 111 184 f \$0;
#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X connect 0 0 5 0;
#X connect 1 0 6 0;
#X connect 2 0 3 0;
#X connect 4 1 18 0;
#X connect 5 0 1 0;
#X connect 6 0 12 0;
#X connect 6 1 2 0;
#X connect 7 0 14 0;
#X connect 8 0 13 0;
#X connect 9 0 8 0;
#X connect 11 0 5 0;
#X connect 12 0 4 0;
#X connect 13 0 10 0;
#X connect 14 1 9 0;
#X connect 15 0 14 0;
#X connect 16 0 17 1;
#X connect 17 0 7 0;
#X connect 17 1 15 0;
#X connect 18 0 19 0;
#X connect 19 0 17 0;
#X connect 20 0 17 1;
#X restore 71 118 pd draw;
#X obj 44 130 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
-1 0 1;
#X msg 152 120 automaton fsm-help-2;
#X connect 4 0 6 0;
#X connect 5 0 6 0;
#X connect 7 0 72 0;
#X connect 8 0 32 0;
#X connect 9 0 11 0;
#X connect 10 0 9 0;
#X connect 11 0 33 0;
#X connect 12 0 33 0;
#X connect 13 0 32 0;
#X connect 14 0 13 0;
#X connect 15 0 9 0;
#X connect 16 0 14 0;
#X connect 17 0 34 0;
#X connect 18 0 17 0;
#X connect 19 0 18 0;
#X connect 20 0 22 0;
#X connect 21 0 20 0;
#X connect 22 0 34 0;
#X connect 23 0 27 0;
#X connect 24 0 27 1;
#X connect 25 0 27 2;
#X connect 26 0 27 3;
#X connect 27 0 55 1;
#X connect 28 0 29 0;
#X connect 29 0 55 0;
#X connect 29 1 27 0;
#X connect 30 0 23 0;
#X connect 30 0 24 0;
#X connect 30 0 25 0;
#X connect 30 0 26 0;
#X connect 31 0 35 0;
#X connect 36 0 44 0;
#X connect 37 0 44 0;
#X connect 38 0 45 0;
#X connect 39 0 45 0;
#X connect 40 0 43 0;
#X connect 41 0 43 0;
#X connect 42 0 43 0;
#X connect 46 0 49 0;
#X connect 47 0 49 0;
#X connect 48 0 47 0;
#X connect 51 0 48 0;
#X connect 52 0 49 0;
#X connect 53 0 49 0;
#X connect 55 0 31 0;
#X connect 56 0 6 0;
#X connect 57 0 49 0;
#X connect 58 0 49 0;
#X connect 59 0 49 0;
#X connect 61 0 60 0;
#X connect 62 0 60 0;
#X connect 63 0 60 0;
#X connect 64 0 63 0;
#X connect 65 0 64 0;
#X connect 66 0 60 0;
#X connect 67 0 60 0;
#X connect 68 0 60 0;
#X connect 69 0 60 0;
#X connect 70 0 44 0;
#X connect 71 0 45 0;
#X connect 72 0 1 0;
#X connect 73 0 45 0;
#X connect 74 0 24 0;
#X connect 74 0 25 0;
#X connect 74 0 26 0;
#X connect 77 0 6 0;





More information about the Pd-cvs mailing list