
// Вернёт номер узла графа с конечным состоянием.
var GetNumberUnitMarkerFinal(SYS){
	nets=SYS->G.getMARKER(#,0,"",0,"FINISH");
	if(nets.size())return nets[0][0];
	return "Нет FINISHа!";
}


// Вернёт все возможные пути к состоянию модели. Циклов не должно быть.
var WhotListWaysToX(SYS,X){
	G=&SYS->G;
	ways={};
	FinderWaysToX(&ways,G,{},0,X);
	return ways;
}



void FinderWaysToX(ways,G,way,A,X){
	for(t=0;t<way.size();++t)if(way[t]==A)return;
	way.push(A);
	if(A==X){
		ways->push(way);
		return;
		}
	W=G->getNET(A,0,#,1,#);
	for(t=0;t<W.size();++t){
		FinderWaysToX(ways,G,way,W[t][1],X);
		}
}


// Вернёт все возможные пути проходящие через состоянию модели. Циклов не должно быть.
var WhotListProxoditPoX(SYS,X){
	G=&SYS->G;
	ways={};
	FinderWaysProxoditPoX(&ways,G,{},0,X,0);
	return ways;
}


void FinderWaysProxoditPoX(ways,G,way,A,X,ok){
	way.push(A);
	if(A==X)ok=1;
	W=G->getNET(A,0,#,1,#);
	for(t=0;t<W.size();++t){
		FinderWaysProxoditPoX(ways,G,way,W[t][1],X,ok);
		}
	if(!t && ok)ways->push(way);
}


// Вернёт все состояния на заданном шаге.
var getAllObjektsForStep(SYS,nStep){
	if(!nStep)return {0};
	G=&SYS->G;
	List={0};
	Level=0;
	while(1){
		S=(set)0;
		for(i=0;i<List.length();++i){
			nets=G->getNET(List[i],0,"",1,#);
			for(j=0;j<nets.length();++j)S.insert(nets[j][0]);
			}
		List=(vector)S;
		++Level;
		if(Level>=nStep)break;
		}
	return List;
}


//Вернёт распечатку множества состояний
var getStringObjects(SYS,List){
	row={};
	for(i=0;i<List.length();++i){
		str="";
		X=&SYS->m[List[i]];
		if(isset(SYS->functions.toString))str=SYS->functions.toString.run(X);
			else str=getAuthorForm(X);
		row.push(str);
		}
	formatZvitov=0;
	if(isset(SYS->formatZvitov))formatZvitov=SYS->formatZvitov;
	if(formatZvitov)return getzvit(row);
	str="";
	for(i=0;i<row.length();++i){
		if(i)str+="\n";
		str+=row[i];
		}
	return str;
}



int computeCountAllShotWays(SYS){
	FindWAYS(SYS);
	if(!isset(SYS->tableWAY))return 0;
	G=&SYS->G;
	table=&SYS->tableWAY;
	Xmap=(map)0;
	units={0};
	Xmap[0]=1;
	pos=2;
	countA=1;
	countB=0;
	while(units.size()){
		n=units.pop_begin();
		nws=Xmap[n];
		W=G->getNET(n,0,#,1,#);
		next={};
		for(t=0;t<W.size();++t)next.push(W[t][1]);
		next=(vector)(set)next;
		for(t=0;t<next.size();++t){
			k=next[t];
			if(isset((*table)[k]))if((*table)[k]==pos){
				s=nws;
				if(Xmap.isset(k))s+=Xmap[k];
				Xmap[k]=s;
				if(units.findOf(k)>=0)continue;
				units.push(k);
				++countB;
				}
			}
		--countA;
		if(!countA){
			++pos;
			countA=countB;
			countB=0;
			}
		}
	return nws;
}



var GetParametersForWay(SYS,way){
	R={};
	for(i=1;i<way.size();++i){
		X=&SYS->m[way[i-1]];
		Q=&SYS->m[way[i]];
		ok=0;
		for(t=0;t<SYS->functions.methods.size();++t){
			methodX=SYS->functions.parameters[t];
			args=methodX.run(X);
			methodX=SYS->functions.methods[t];
			for(j=0;j<args.size();++j){
				Y=*X;
				methodX.run1({&Y}+args[j]);
				if(*Y==*Q){
					R.push({t}+args[j]);
					ok=1;
					break 2;
					}
				}
			}
		if(!ok){
			R.push("Error:"+(i-1)+"->");
			/*
			trace(getAuthorForm(X) + " =?> " + getAuthorForm(Q));
			trace(getAuthorForm(&args));
			*/
			}
		}
	return R;
}


var getAllFinalSYS(SYS){
	v={};
	nets=SYS->G.getMARKER(#,0,"",0,"FINISH");
	for(i=0;i<nets.size();++i)v.push(nets[i][0]);
	return v;
}
