确定的有限状态自动机
有限自动机作为一种识别装置,能准确的识别正规集。一个确定的有限状态自动机M是一个五元组:
- K是一个有穷集,它的每一个元素成为一个状态。
- 是一个有穷字母表,它的每个元素称为一个输入符号,所以也可以称 为输入符号表。
- f是转换函数,是 上的映像。
- ,是唯一的一个终态。
- ,是一个终态集,终态也称为可接受状态或结束状态。
预备知识
要看懂有限机代码需要几个前提:typedef函数指针、互斥锁、循环队列。
1.typedef 函数指针
//typedef 返回类型(*新类型)(参数表)
//从内存上看,函数指针存储的就是函数的地址
#include<stdio.h>
typedef void (*Funcall)(char*,int);
void information(char* name,int years)
{
printf("my name is %s and
I'm %d years old;\n",name,years);
}
void fruit(char* name,int price)
{
printf("%s price is %d\n",name,price);
}
int main()
{
Funcall pFuncall;
pFuncall = information;
(*pFuncall)("wanghua",18);
pFuncall = fruit;
(*pFuncall)("apple",5);
return 0;
}
2.循环队列
循环队列有两种实现形式,一种为数组,另一种为链表,有限自动机的输入一般进行宏定义,因此使用数组方式构成循环链表比较合适。数组从物理空间角度就是一块连续的地址,要从逻辑上实现循环队列需要进行处理,我们采用空出一个空间的方式,下面公式展示循环链表空、满、插入、删除操作的条件和计算:
#define MAX 100
typedef struct{
int input[MAX];
int head;
int tail;
}Queue,*pQueue;
- 判断循环队列为空:head == tail
- 判断循环队列满:(tail + 1) % MAX == head
- 插入循环队列元素: tail = (tail + 1 ) % MAX
- 删除循环队列元素:head = ( head + 1 ) % MAX
3.互斥锁
学习过操作系统的童鞋应该对线程同步与互斥很熟悉,我们的循环列表是一个互斥资源,同一时间只允许一个写操作或读操作,因此对循环列表的所有操作必须在加锁和解锁之间进行。
1、首先定义互斥锁变量,并初始化
pthread_mutex_t mutex_lock;
pthread_mutex_init(&mutex_lock,NULL);
2、在操作前对互斥量进行加锁操作
pthread_mutex_lock(&mutex_lock);
3、操作完毕后进行解锁操作
pthread_mutex_unlock(&mutex_lock);
代码讲解
- 有限自动机状态分析:
如图1-1所示,{S1、S2、S3、S_trap}为状态,{c1、c2、c3}为输入,{a1、a2、a3}为动作,箭头指向表示在S1的状态下,输入c1,执行动作a1,转换到状态S2。
当依次输入c1、c2、c3、c2时,状态机依次做出上表反应,当状态机遇到某个不能识别的输入时,就会进入陷阱状态,进入陷阱状态后无论输入什么都不会跳出。
状态 | 输入 | 动作 | 新状态 |
---|---|---|---|
S1 | c1 | a1 | S2 |
S2 | c2 | a2 | S3 |
S3 | c3 | a3 | S1 |
S1 | c2 | S_trap | S_trap |
2. 宏定义
//定义状态State
typedef int State;
#define States 4
#define State_1 0
#define State_2 1
#define State_3 2
#define State_trap 3
//定义输入Conditions
typedef int Conditions;
#define Conditions 3
#define Condition_1 0
#define Condition_2 1
#define Condition_3 2
//定义循环队列状态
typedef int bool;
#define OK 0
#define NODATA 1
#define OVERFLOW 2
3.结构体分析
从状态转换过程来看,我们需要一个状态机存储当前状态,一个跳转结构实现跳转过程,一个循环队列用于存储输入。
//状态机
typedef struct{
State current;
bool inTransition; //判断状态机是否在转换状态
Queue queue; //存储输入
}StateMachine,*pStateMachine;
//跳转结构,此结构需要函数指针的配合
typedef void (*Action)(State state,Condition condition);
typedef struct{
State next;
Action action; //动作函数指针,用来触发动作
}Transition,*pTransition;
//循环队列
typedef int bool
#define MAX 100;
typedef struct{
int queue[MAX];
int head;
int tail;
bool overflow;
}Queue,*pQueue;
4 .跳转功能实现
/*******************************************/
//跳转关系
//[s1,c1,a1,s2]
Transition t1 = { State_2, action_1};
//[s2,c2,a2,s3]
Transition t2 ={ State_3,action_2};
//[s3,c3,a3,s1]
Transition t3 = {State_1,action_3};
//[s1,c2,s_trap,s_trap]
Transition trap ={State_trap,action_trap};
/************************************************/
//定义动作
void action_1(State state,Condition condition)
{
printf("Action_1 is running\n");
}
void action_2(State state,Condition condition)
{
printf("Action_2 is running\n");
}
void action_3(State state,Condition condition)
{
printf("Action_3 is running\n");
}
void action_trap(State state,Condition condition)
{
printf("Action_trap is running\n");
}
/************************************************/
//定义跳转表,看不懂的可以看下面跳转表格
pTransition transition_table[States][Conditions]={
&t1,&trap,&trap,
&trap,&trap,&t2,
&trap,&trap,&t3,
&trap,&trap,&trap,
};
跳转表 | c1 | c2 | c3 |
---|---|---|---|
s1 | action_1 | action_trap | action_trap |
s2 | action_trap | action_2 | action_trap |
s3 | action_trap | action_trap | action_3 |
trap | action_trap | action_trap | action_trap |
5.循环队列功能实现:
//入列
int push(pQueue queue,Condition c)
{
pthread_mutex_lock(&mutex_lock); //上锁
if(queue->head == queue->tail+1) //队列满
{
queue->overflow = true;
local_irq_restore(flags); //开终端
return OVERFLOW;
}
else
{
queue->queue[queue->tail] = c;
queue->tail = (queue->tail + 1) % MAX;
}
pthread_mutex_unlock(&mutex_lock); //解锁
return OK;
}
//出列
int poll(pQueue queue,Condition *c)
{
pthread_mutex_lock(&mutex_lock); //上锁
if(queue->head == queue->tail) //队列空
{
local_irq_restore(flags); //开中断
return NODATA;
}
else
{
*c = queue->queue[queue->head];
queue->overflow = false;
queue->head = (queue->head+1) % MAX;
}
pthread_mutex_unlock(&mutex_lock); //解锁
return OK;
}
6.状态机功能实现
//状态机初始化
void initialize(pStateMachine machine,State s)
{
machine->current = s;
machine->inTransition = false;
machine->queue.head =0 ;
machine->queue.overflow = false;
}
//动作执行
static State takeAction(pStateMachine machine,Condition condition)
{
State current = machine->current;
pTransition p = transition_table[current][condition];
(*(p->action))(current,condition);
current = t->next;
machine->current = current;
return current;
}
//实现多输入处理
State multask(pStateMachine machine,Condition condition)
{
int status;
Condition next_condition;
if(machine->inTransition)
{
push(&(machine->queue),condition);
return ;
}
else
{
machine->inTransition = true;
current = takeAction(machine,condition);
status = poll(&(machine->queue),&next_condition);
while(status == OK)
{
takeAction(machine,next_condition);
status = poll(&(machine->queue),&next_condition);
}
machine->inTransition = false;
return current;
}
}
测试函数
int main()
{
Statemachine machine;
initialStatemachine(&machine,State_1);
multiplyTask(&machine,Condition_1);
multiplyTask(&machine,Condition_2);
return 0;
}
完整代码
#include<stdio.h>
#include<pthread.h>
typedef int State; //状态
typedef int Condition; //输入
typedef void (*Action)(State state,Condition condition); //函数指针
//宏定义
#define States 4
#define State_1 0
#define State_2 1
#define State_3 2
#define State_trap 3
#define Conditions 3
#define Condition_1 0
#define Condition_2 1
#define COndition_3 2
#define OK 0
#define NODATA 1
#define OVERFLOW 2
#define MAX 100
//跳转结构体
typedef struct{
State next;
Action action;
}Transition,*pTransition;
//循环队列结构体
typedef struct{
int queue[MAX];
int head;
int tail;
int overflow;
}Queue,*pQueue;
//状态机结构体
typedef struct{
State current;
int inTransition;
Queue squeue;
}Statemachine,*pStatemachine;
//动作函数声明
void action_1(State state,Condition condition);
void action_2(State state,Condition condition);
void action_3(State state,Condition condition);
void action_trap(State state,Condition condition);
//定义互斥锁变量
pthread_mutex_t mutex_lock;
//[s1,c1,a1,s2]
Transition t1 = {State_2,action_1};
//[s2,c2,a2,s3]
Transition t2 = {State_3,action_2};
//[s3,c3,a3,s1]
Transition t3 = {State_1,action_3};
//[s1,c2,trap,trap]
Transition trap = {State_trap,action_trap};
//动作函数
void action_1(State state,Condition condition)
{
printf("action_1 is running\n");
printf("State is %d and Condition is %d \n",state,condition);
}
void action_2(State state,Condition condition)
{
printf("action_2 is running\n");
printf("State is %d and Condition is %d\n ",state,condition);
}
void action_3(State state,Condition condition)
{
printf("action_3 is running\n");
printf("State is %d and Condition is %d \n",state,condition);
}
void action_trap(State state,Condition condition)
{
printf("action_trap is running\n");
printf("State is %d and Condition is %d\n ",state,condition);
}
//转换表
pTransition transition_table[States][Conditions]=
{
&t1,&trap,&trap,
&trap,&t2,&trap,
&trap,&trap,&t3,
&trap,&trap,&trap,
};
//插入循环表
int push(pQueue squeue,Condition condition)
{
pthread_mutex_lock(&mutex_lock);
if(squeue->head == (squeue->tail+ 1)) //队列满
{
squeue->overflow = true;
return OVERFLOW ;
}
else
{
squeue->overflow = false;
squeue->queue[squeue->tail]= condition;
squeue->tail = (squeue->tail + 1 ) % MAX;
}
pthread_mutex_unlock(&mutex_lock);
return OK;
}
//出队列
int poll(pQueue squeue,Condition *c)
{
pthread_mutex_init(&mutex_lock,NULL);
pthread_mutex_lock(&mutex_lock);
if(squeue->head == squeue->tail) //空队列
{
squeue->overflow = false;
return NODATA;
}
else
{
squeue->overflow = false ;
*c= squeue->queue[squeue->head];
squeue->head = (squeue->head + 1) % MAX ;
}
pthread_mutex_unlock(&mutex_lock);
return OK;
}
//状态机初始化
void initialStatemachine(pStatemachine machine,State state)
{
machine->current = state;
machine->inTransition = false;
machine->squeue.head = 0 ;
machine->squeue.tail = 0;
machine->squeue.overflow = false;
}
//动作执行
static State takeAction(pStatemachine machine,Condition condition)
{
State current = machine->current;
pTransition t = transition_table[machine->current][condition];
(*(t->action))(machine->current,condition);
current = t->next;
machine->current = current;
return current;
}
//多输入执行
int multiplyTask(pStatemachine machine,Condition condition)
{
int status;
int next_condition;
State current;
if(machine->inTransition)
{
push(&(machine->squeue),condition);
return OK;
}
else
{
machine->inTransition = true;
current = takeAction(machine,condition);
status = poll(&(machine->squeue),&next_condition);
while(status == OK)
{
current = takeAction(machine,next_condition);
status = poll(&(machine->squeue),&next_condition);
}
machine->inTransition = false;
}
return current;
}
int main()
{
Statemachine machine;
initialStatemachine(&machine,State_1);
multiplyTask(&machine,Condition_1);
multiplyTask(&machine,Condition_2);
return 0;
}