Example #1
0
func read(path string) (*fsm.Adapter, *partition.Partition) {
	// Read file and construct FSM
	f, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	a := fsm.NewAdapter(fsm.DotParser{})
	a.Scan(bufio.NewScanner(f))
	m := a.FSM()
	states, inputs, outputs := m.States(), m.Inputs(), m.Outputs()

	// Construct transition (f) and output (g) functions
	fs := make([]func(int) int, 0, inputs)
	gs := make([]func(int) int, 0, inputs)
	for input := 0; input < inputs; input++ {
		f, _ := m.TransitionFunction(input)
		fs = append(fs, f)
		g, _ := m.OutputFunction(input)
		gs = append(gs, g)
	}

	// Construct the partition
	p := partition.New(states, outputs, gs...)
	p.Refine(0, fs...)

	// Print results
	var not string
	if p.Size() != states {
		not = "not "
	}
	fmt.Printf("FSM %s is %sminimal.\n", path, not)

	return a, p
}
Example #2
0
func main() {
	if len(os.Args) != 3 {
		fmt.Printf("Usage: %s <fsm1.dot> <fsm2.dot>\n", os.Args[0])
		os.Exit(1)
	}

	a1, _ := read(os.Args[1])
	a2, _ := read(os.Args[2])

	// Add transitions of a2 to a1
	for t := range a2.Transitions() {
		from := "a2_" + t.From
		input := t.Input
		output := t.Output
		to := "a2_" + t.To

		if _, err := a1.Input(input); err != nil {
			panic(err)
		}

		a1.AddState(from)
		a1.AddState(to)
		a1.AddOutput(output)
		a1.AddTransition(from, input, output, to)
	}

	// Determine start states
	start1 := "s0"
	start2 := "a2_s0"
	if _, err := a1.State(start2); err != nil {
		panic(err)
	}

	// Make product FSM
	product := a1.FSM()
	states, inputs, outputs := product.States(), product.Inputs(), product.Outputs()

	// Construct partition for product FSM
	fs := make([]func(int) int, 0, inputs)
	gs := make([]func(int) int, 0, inputs)
	for input := 0; input < inputs; input++ {
		f, _ := product.TransitionFunction(input)
		fs = append(fs, f)
		g, _ := product.OutputFunction(input)
		gs = append(gs, g)
	}

	p := partition.New(states, outputs, gs...)
	p.Refine(0, fs...)

	// Print witness (minimal separating sequence) for start states
	s, _ := a1.State(start1)
	t, _ := a1.State(start2)
	witness := p.Witness(s, t)
	fmt.Println("A minimal separating sequence for the two start states is:")
	for _, i := range witness {
		input, _ := a1.InputName(i)
		fmt.Print(input + " ")
	}
	fmt.Print("\n")

}