[Pntool-developers] SF.net SVN: pntool:[246]
Brought to you by:
compaqdrew,
miordache
|
From: <mio...@us...> - 2011-04-08 22:36:53
|
Revision: 246
http://pntool.svn.sourceforge.net/pntool/?rev=246&view=rev
Author: miordache
Date: 2011-04-08 22:36:44 +0000 (Fri, 08 Apr 2011)
Log Message:
-----------
update
Modified Paths:
--------------
2009_version/codegen/Makefile
Makefile
newcodegen/Makefile
pnheaders/insert.c
Added Paths:
-----------
2009_version/
2009_version/Makefile09
2009_version/codegen/
2009_version/pnheaders/
2009_version/spnbox09/
2009_version/spnbox09/Makefile
2009_version/spnbox09/MemoryManager.c
2009_version/spnbox09/MemoryManager.h
2009_version/spnbox09/actn.c
2009_version/spnbox09/admcon.c
2009_version/spnbox09/asiph.c
2009_version/spnbox09/avpr.c
2009_version/spnbox09/chkcons.c
2009_version/spnbox09/deallocation.c
2009_version/spnbox09/dp.c
2009_version/spnbox09/dp4.c
2009_version/spnbox09/extendedmatrix.c
2009_version/spnbox09/extendedmatrix.h
2009_version/spnbox09/fvpr.c
2009_version/spnbox09/gcdv.c
2009_version/spnbox09/ilpadm.c
2009_version/spnbox09/invar.c
2009_version/spnbox09/ipslv.c
2009_version/spnbox09/ipsolve.c
2009_version/spnbox09/isadm.c
2009_version/spnbox09/issiph.c
2009_version/spnbox09/linenf.c
2009_version/spnbox09/matrixmath.c
2009_version/spnbox09/matrixmath.h
2009_version/spnbox09/mroadm.c
2009_version/spnbox09/msplit.c
2009_version/spnbox09/nltrans.c
2009_version/spnbox09/pn2acpn.c
2009_version/spnbox09/pn2eacpn.c
2009_version/spnbox09/reduce.c
2009_version/spnbox09/spnbox.h
2009_version/spnbox09/supervis.c
2009_version/spnbox09/tactn.c
2009_version/spnbox09/tests/
2009_version/spnbox09/tests/Makefile
2009_version/spnbox09/tests/StructuredIO.c
2009_version/spnbox09/tests/StructuredIO.h
2009_version/spnbox09/tests/pnexample.c
2009_version/spnbox09/tests/test-actn.c
2009_version/spnbox09/tests/test-actn.txt
2009_version/spnbox09/tests/test-admcon.c
2009_version/spnbox09/tests/test-asiph.c
2009_version/spnbox09/tests/test-asiph.txt
2009_version/spnbox09/tests/test-avpr.c
2009_version/spnbox09/tests/test-avpr.txt
2009_version/spnbox09/tests/test-dp.c
2009_version/spnbox09/tests/test-dp.txt
2009_version/spnbox09/tests/test-extendedmatrix.c
2009_version/spnbox09/tests/test-extendedmatrix.txt
2009_version/spnbox09/tests/test-fvpr.c
2009_version/spnbox09/tests/test-fvpr.txt
2009_version/spnbox09/tests/test-gcdv.c
2009_version/spnbox09/tests/test-gcdv.txt
2009_version/spnbox09/tests/test-ilpadm.c
2009_version/spnbox09/tests/test-ilpadm.txt
2009_version/spnbox09/tests/test-invar.c
2009_version/spnbox09/tests/test-invar.txt
2009_version/spnbox09/tests/test-ipslv.c
2009_version/spnbox09/tests/test-ipsolve.c
2009_version/spnbox09/tests/test-ipsolve.txt
2009_version/spnbox09/tests/test-isadm.c
2009_version/spnbox09/tests/test-isadm.txt
2009_version/spnbox09/tests/test-issiph.c
2009_version/spnbox09/tests/test-issiph.txt
2009_version/spnbox09/tests/test-linenf.c
2009_version/spnbox09/tests/test-linenf.txt
2009_version/spnbox09/tests/test-matrixmath.c
2009_version/spnbox09/tests/test-matrixmath.txt
2009_version/spnbox09/tests/test-mroadm.c
2009_version/spnbox09/tests/test-mroadm.txt
2009_version/spnbox09/tests/test-msplit.c
2009_version/spnbox09/tests/test-msplit.txt
2009_version/spnbox09/tests/test-nltrans.c
2009_version/spnbox09/tests/test-nltrans.txt
2009_version/spnbox09/tests/test-pn2acpn.c
2009_version/spnbox09/tests/test-pn2acpn.txt
2009_version/spnbox09/tests/test-pn2eacpn.c
2009_version/spnbox09/tests/test-pn2eacpn.txt
2009_version/spnbox09/tests/test-reduce.c
2009_version/spnbox09/tests/test-reduce.txt
2009_version/spnbox09/tests/test-supervis.c
2009_version/spnbox09/tests/test-supervis.txt
2009_version/spnbox09/tests/test-tactn.c
2009_version/spnbox09/tests/test-tactn.txt
2009_version/spnbox09/tests/test.c
2009_version/spnbox09/tests/test.h
LICENSE/
LICENSE/ANTLR3_LICENSE.txt
LICENSE/LICENSE.txt
LICENSE/README.txt
README.txt
pnheaders/Makefile
Removed Paths:
-------------
ANTLR3_LICENSE.txt
LICENSE.txt
Makefile09
codegen/
pnheaders09/
Copied: 2009_version/Makefile09 (from rev 245, Makefile09)
===================================================================
--- 2009_version/Makefile09 (rev 0)
+++ 2009_version/Makefile09 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,34 @@
+# This is the make file of the 2009 version of the program.
+
+COMPILER=gcc -g
+
+PNHEADERS=pnheaders
+SPNBOX=spnbox09
+CODEGEN=codegen
+CODEGENOBJS = codegen/src
+TRANSLATOR=../translator
+
+ct09: objectfiles main_function.o
+ $(COMPILER) -o ct09 $(PNHEADERS)/*.o $(CODEGENOBJS)/*.o $(SPNBOX)/*.o \
+ main_function.o $(SPNBOX)/*.a $(TRANSLATOR)/libtranslator.a
+
+objectfiles:
+ cd $(PNHEADERS); make
+ cd $(CODEGEN); make static
+ cd $(SPNBOX); make
+ cd $(TRANSLATOR); make
+
+main_function.o: $(PNHEADERS)/main_function.c $(PNHEADERS)/pns.h $(SPNBOX)/spnbox.h $(CODEGEN)/src/codegen.h
+ $(COMPILER) -c $(PNHEADERS)/main_function.c -Ispnbox09 -I$(CODEGEN)/src -I$(PNHEADERS)
+
+clean:
+ rm -f main_function.o
+ cd $(PNHEADERS); make clean
+ cd codegen; make clean
+ cd $(TRANSLATOR); make clean
+ cd $(SPNBOX); make clean
+
+distclean: clean
+ cd codegen; make distclean
+ cd $(TRANSLATOR); make distclean
+
Modified: 2009_version/codegen/Makefile
===================================================================
--- codegen/Makefile 2011-04-02 00:10:24 UTC (rev 245)
+++ 2009_version/codegen/Makefile 2011-04-08 22:36:44 UTC (rev 246)
@@ -2,7 +2,8 @@
COMPILER=gcc -g
-PNHEADERS = ../pnheaders/general.o ../pnheaders/matrix.o ../pnheaders/pns.o
+PNHEADERS = ../pnheaders/general.c ../pnheaders/matrix.c ../pnheaders/pns.c
+PNOBJS = ../pnheaders/general.o ../pnheaders/matrix.o ../pnheaders/pns.o
STANDALONE = src/main.o
OBJS = src/codegen.o src/plantCompiler.o src/supervisorCompiler.o src/petriNetSerializer.o src/text.o src/MakeGen.o
B = \033[32m
@@ -10,21 +11,21 @@
-standalone: pnslib static $(STANDALONE)
+standalone: pnslib static $(STANDALONE) $(PNOBJS)
echo "$(B)Making standalone files...$(E)"
$(COMPILER) -c $(STANDALONE)
echo "$(B)Linking it all up...$(E)"
- $(COMPILER) -o codegen $(OBJS) $(PNHEADERS) $(STANDALONE)
+ $(COMPILER) -o codegen $(OBJS) $(PNOBJS) $(STANDALONE)
echo "$(B)Done$(E)"
-pnslib: $(PNHEADERS)
+pnslib: $(PNHEADERS)
echo "$(B) Precompiling pnheaders...$(E)"
$(COMPILER) -c $(PNHEADERS)
echo "$(B)Done$(E)"
static: $(OBJS) pnslib
echo "$(B) Making pure codegen...$(E)"
- $(COMPILER) -c $(OBJS) $(PNHEADERS) -I../pnheaders
+ #$(COMPILER) -c $(OBJS) -I../pnheaders
echo "$(B)Done$(E)"
src/%.o : src/%.c
$(COMPILER) -I../pnheaders -o src/$*.o -c src/$*.c
@@ -41,6 +42,6 @@
echo "$(B)Done$(E)"
distclean: clean
echo "$(B)Making distclean...$(E)"
- rm -f $(PNHEADERS)
+ rm -f $(PNOBJS)
echo "$(B)Done$(E)"
Added: 2009_version/spnbox09/Makefile
===================================================================
--- 2009_version/spnbox09/Makefile (rev 0)
+++ 2009_version/spnbox09/Makefile 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,108 @@
+#This is the makefile for all spnbox functions.
+#It is called by the pntool makefile to create object code for all the functions.
+
+COMPILER=gcc -g
+PNHEADERS=../pnheaders
+
+all: actn.o admcon.o asiph.o avpr.o chkcons.o deallocation.o dp.o\
+ extendedmatrix.o fvpr.o gcdv.o invar.o ilpadm.o ipslv.o ipsolve.o isadm.o\
+ issiph.o linenf.o matrixmath.o MemoryManager.o mroadm.o msplit.o nltrans.o\
+ pn2acpn.o pn2eacpn.o reduce.o supervis.o tactn.o liblpsolve55.a
+
+actn.o: actn.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c actn.c
+
+admcon.o: admcon.c spnbox.h matrixmath.h extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c admcon.c
+
+asiph.o: asiph.c spnbox.h extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c asiph.c
+
+avpr.o: avpr.c $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c avpr.c
+
+chkcons.o: chkcons.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h
+ $(COMPILER) -c chkcons.c
+
+deallocation.o: deallocation.c spnbox.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c deallocation.c
+
+dp.o: dp.c spnbox.h matrixmath.h extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h
+ $(COMPILER) -c dp.c
+
+dp4.o: dp4.c spnbox.h matrixmath.h extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h
+ $(COMPILER) -c dp4.c
+
+extendedmatrix.o: extendedmatrix.c extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c extendedmatrix.c
+
+fvpr.o: fvpr.c $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c fvpr.c
+
+gcdv.o: gcdv.c $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c gcdv.c
+
+invar.o: invar.c spnbox.h matrixmath.h MemoryManager.h extendedmatrix.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c invar.c
+
+ilpadm.o: ilpadm.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h
+ $(COMPILER) -c ilpadm.c
+
+ipslv.o: ipslv.c spnbox.h ../../third-party/lp_solve_5.5/lp_lib.h
+ $(COMPILER) -c ipslv.c
+
+ipsolve.o: ipsolve.c spnbox.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c ipsolve.c
+
+isadm.o: isadm.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c isadm.c
+
+issiph.o: issiph.c spnbox.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c issiph.c
+
+linenf.o: linenf.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c linenf.c
+
+matrixmath.o: matrixmath.c matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c matrixmath.c
+
+MemoryManager.o: MemoryManager.c MemoryManager.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c MemoryManager.c
+
+mroadm.o: mroadm.c spnbox.h $(PNHEADERS)/matrix.h $(PNHEADERS)/general.h matrixmath.h
+ $(COMPILER) -c mroadm.c
+
+msplit.o: msplit.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c msplit.c
+
+nltrans.o: nltrans.c spnbox.h MemoryManager.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c nltrans.c
+
+pn2acpn.o: pn2acpn.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c pn2acpn.c
+
+pn2eacpn.o: pn2eacpn.c spnbox.h MemoryManager.h matrixmath.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c pn2eacpn.c
+
+reduce.o: reduce.c spnbox.h $(PNHEADERS)/general.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h
+ $(COMPILER) -c reduce.c
+
+supervis.o: supervis.c spnbox.h matrixmath.h $(PNHEADERS)/matrix.h
+ $(COMPILER) -c supervis.c
+
+tactn.o: tactn.c spnbox.h $(PNHEADERS)/matrix.h $(PNHEADERS)/pns.h matrixmath.h MemoryManager.h
+ $(COMPILER) -c tactn.c
+
+liblpsolve55.a: ../../third-party/lp_solve_5.5/lpsolve55/liblpsolve55.a
+ cp ../../third-party/lp_solve_5.5/lpsolve55/liblpsolve55.a liblpsolve55.a
+
+../../third-party/lp_solve_5.5/lpsolve55/liblpsolve55.a:
+ cd ../../third-party/lp_solve_5.5; make -f Makefile.Linux lib
+
+clean:
+ rm -fv *.o *.a
+ cd ../../third-party/lp_solve_5.5; make -f Makefile.Linux clean
+
+clean-partial:
+ rm -fv *.o
+
Added: 2009_version/spnbox09/MemoryManager.c
===================================================================
--- 2009_version/spnbox09/MemoryManager.c (rev 0)
+++ 2009_version/spnbox09/MemoryManager.c 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,201 @@
+#include "MemoryManager.h"
+
+inline void ManageMatrix(MemoryManager* mgr, matrix* m)
+{
+ matrix **matrices;
+ if(mgr->nextm == mgr->lengthm)
+ {
+ if (! (matrices = realloc(mgr->matrices, sizeof(matrix*) * (mgr->lengthm + mgr->addressblockm))))
+ {
+ merror(0, "Out of memory");
+ return;
+ }
+ mgr->matrices = matrices;
+ mgr->lengthm += mgr->addressblockm;
+ }
+ mgr->matrices[mgr->nextm++] = m;
+}
+
+inline void ManageMemory(MemoryManager* mgr, void* mem)
+{
+ void** memory;
+ if (mgr->next == mgr->length)
+ {
+ if (! (memory = realloc(mgr->memory, sizeof(void*) * (mgr->length + mgr->addressblock))))
+ {
+ merror(0, "Out of memory");
+ return;
+ }
+ mgr->memory = memory;
+ mgr->length += mgr->addressblock;
+ }
+ mgr->memory[mgr->next++] = mem;
+}
+
+inline void* mmalloc(MemoryManager* mgr, size_t nbytes)
+{
+ void **memory;
+ if(mgr->next == mgr->length)
+ {
+ if (! (memory = realloc(mgr->memory, sizeof(void*) * (mgr->length + mgr->addressblock))))
+ {
+ merror(0, "Out of memory");
+ return;
+ }
+ mgr->memory = memory;
+ mgr->length += mgr->addressblock;
+ }
+ return mgr->memory[mgr->next++] = tmalloc(nbytes);
+}
+
+inline void* mcalloc(MemoryManager* mgr, size_t n, size_t nbytes)
+{
+ void **memory;
+ if(mgr->next == mgr->length)
+ {
+ if (! (memory = realloc(mgr->memory, sizeof(void*) * (mgr->length + mgr->addressblock))))
+ {
+ merror(0, "Out of memory");
+ return;
+ }
+ mgr->memory = memory;
+ mgr->length += mgr->addressblock;
+ }
+ return mgr->memory[mgr->next++] = tcalloc(n, nbytes);
+}
+
+inline void MAllocateMatrixType(MemoryManager* mgr, int type, matrix* m, int rows, int cols)
+{
+ AllocateMatrixType(type, m, rows, cols);
+ if (rows || cols)
+ {
+ ManageMatrix(mgr, m);
+ }
+}
+
+void FreeMemory(MemoryManager* mgr)
+{
+ int i;
+ for (i = 0; i < mgr->nextm; i++)
+ {
+ if (mgr->matrices[i]->type) DeallocateMatrix(mgr->matrices[i]);
+ }
+ free(mgr->matrices);
+ mgr->matrices = 0;
+ for (i = 0; i < mgr->next; i++)
+ {
+ free(mgr->memory[i]);
+ }
+ free(mgr->memory);
+ mgr->memory = 0;
+}
+
+MemoryManager CreateMemoryManager(int InitialLength, int InitialMatrices, int AddressBlockSize, int MatrixAddressBlockSize)
+{
+ MemoryManager mgr;
+ mgr.next = 0;
+ mgr.nextm = 0;
+ if (InitialLength <= 0) InitialLength = 1;
+ if (InitialMatrices <= 0) InitialMatrices = 1;
+ if (AddressBlockSize <= 5) AddressBlockSize = 5;
+ if (MatrixAddressBlockSize <= 5) MatrixAddressBlockSize = 5;
+ mgr.length = InitialLength;
+ mgr.lengthm = InitialMatrices;
+ mgr.memory = tcalloc(InitialLength, sizeof(void*));
+ mgr.matrices = tcalloc(InitialMatrices, sizeof(void*));
+ mgr.addressblock = AddressBlockSize;
+ mgr.addressblockm = MatrixAddressBlockSize;
+ return mgr;
+}
+
+/*CreateMemoryGrower initializes a memory grower structure.*/
+MemoryGrower CreateMemoryGrower(int pointers, int blocksize)
+{
+ MemoryGrower g;
+ if (pointers < 1 || blocksize < 1)
+ {
+ merror(0, "CREATEMEMORYGROWER: Parameters are non-positive");
+ memset(&g, 0, sizeof(MemoryGrower));
+ return g;
+ }
+
+ g.blocksize = blocksize;
+ g.memories = pointers;
+ g.memory = tcalloc(pointers, sizeof(void*));
+ g.capacity = tcalloc(pointers, sizeof(int));
+ g.next = 0;
+ return g;
+}
+
+void* growMalloc(MemoryGrower* g, void* memory, int size)
+{
+ /*If the pointer is null, allocate some new memory.*/
+ if (! g)
+ {
+ merror(0, "MEMORYGROWER: The pointer to the grower is null");
+ return 0;
+ }
+ if (! memory)
+ {
+ if (g->next == g->memories)
+ {
+ merror(0, "MEMORYGROWER: Too many pointers registered with the grower");
+ return 0;
+ }
+ if (size < g->blocksize) size = g->blocksize;
+ g->memory[g->next] = tmalloc(size);
+ g->capacity[g->next] = size;
+ return g->memory[g->next++];
+ }
+ else
+ {
+ /*Otherwise, find the index of the memory record.*/
+ int i;
+ for (i = 0; i < g->next; i++)
+ {
+ if (memory == g->memory[i]) break;
+ }
+ if (i == g->next)
+ {
+ merror(0, "MEMORYGROWER: The memory did not originate with the grower");
+ return 0;
+ }
+ /*If the request size is smaller than the current capacity return without
+ reallocating.*/
+ if (size < g->capacity[i])
+ {
+ return memory;
+ }
+ /*Otherwise, allocate as necessary.*/
+ {
+ if (size < g->capacity[i] + g->blocksize) size = g->capacity[i] + g->blocksize;
+ void* newMem = tmalloc(size);
+ memcpy(newMem, memory, g->capacity[i]);
+ g->capacity[i] = size;
+ g->memory[i] = newMem;
+ free(memory);
+ return newMem;
+ }
+ }
+}
+
+void* growCalloc(MemoryGrower* g, void* memory, int elementSize, int elements)
+{
+ return growMalloc(g, memory, elementSize * elements);
+}
+
+
+/*FreeMemoryGrower deallocates all the memories pointed to by a memory
+grower.*/
+void FreeMemoryGrower(MemoryGrower* g)
+{
+ if (! g) return;
+ int i;
+ for (i = 0; i < g->next; i++)
+ {
+ free(g->memory[i]);
+ }
+ free(g->memory);
+ free(g->capacity);
+ memset(g, 0, sizeof(MemoryGrower));
+}
Added: 2009_version/spnbox09/MemoryManager.h
===================================================================
--- 2009_version/spnbox09/MemoryManager.h (rev 0)
+++ 2009_version/spnbox09/MemoryManager.h 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,75 @@
+#ifndef MEMORYMANAGER_H
+#define MEMORYMANAGER_H
+
+#include "../pnheaders/general.h"
+#include "../pnheaders/matrix.h"
+
+/*The MemoryManager structure is used to store information about dynamically
+allocated memory so that it can be freed when appropriate. It stores lists
+of pointers to ordinary memory blocks and pointers to matrices.*/
+typedef struct MemoryManager
+{
+ void** memory;
+ int length;
+ int next;
+ int addressblock;
+
+ matrix** matrices;
+ int lengthm;
+ int nextm;
+ int addressblockm;
+} MemoryManager;
+
+/*ManageMatrix adds a matrix to the list of matrices to free later.*/
+inline void ManageMatrix(MemoryManager* mgr, matrix* m);
+
+/*ManageMemory adds a block of memory to the list of blocks to be freed later.*/
+inline void ManageMemory(MemoryManager* mgr, void* mem);
+
+/*mmalloc allocates a block of memory and adds it to the lists.*/
+inline void* mmalloc(MemoryManager* mgr, size_t nbytes);
+
+/*mcalloc allocates a block of memory for an array and adds to the lists.*/
+inline void* mcalloc(MemoryManager* mgr, size_t n, size_t nbytes);
+
+/*MAllocateMatrixType is exactly like AllocateMatrixType except that it adds
+the newly-allocated matrix to the list of matrices to be freed later.*/
+inline void MAllocateMatrixType(MemoryManager* mgr, int type, matrix* m, int rows, int cols);
+
+/*FreeMemory frees the memory blocks and matrices listed by a memory manager.*/
+void FreeMemory(MemoryManager* mgr);
+
+/*CreateMemoryManager initializes a memory manager structure. InitialLength
+and InitialMatrices are the initial sizes of the lists that hold memory block
+and matrix addresses, respectively. Both these parameters must be at least 1 and
+will be set to 1 automatically if passed as less than that.
+AddressBlockSize and MatrixAddressBlockSize are the number of additional
+addresses that memory will be allocated for each time the list of memory block
+addresses or matrix addresses respectively become full. These must be at least
+five and will be set to five automatically if passed as less than that.*/
+MemoryManager CreateMemoryManager(int InitialLength, int InitialMatrices, int AddressBlockSize, int MatrixAddressBlockSize);
+
+/*The MemoryGrower structure maintains the information needed to have a region
+of memory that can be increased in size several times before a time-consuming
+reallocation is necessary.*/
+typedef struct MemoryGrower
+{
+ void** memory;
+ int * capacity;
+ int blocksize, memories, next;
+} MemoryGrower;
+
+/*CreateMemoryGrower initializes a memory grower structure.*/
+MemoryGrower CreateMemoryGrower(int pointers, int blocksize);
+
+/*growMalloc and growCalloc grow the specified piece of memory to the given
+capacity. If the pointer to the memory is null, new memory is allocated. If the
+pointer points to a piece of memory the memorygrower is not responsible for the
+function fails.*/
+void* growMalloc(MemoryGrower* g, void* memory, int size);
+void* growCalloc(MemoryGrower* g, void* memory, int elementSize, int elements);
+
+/*FreeMemoryGrower deallocates all the memories pointed to by a memory
+grower.*/
+void FreeMemoryGrower(MemoryGrower* g);
+#endif
Added: 2009_version/spnbox09/actn.c
===================================================================
--- 2009_version/spnbox09/actn.c (rev 0)
+++ 2009_version/spnbox09/actn.c 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,459 @@
+#include <stdlib.h>
+#include "../pnheaders/matrix.h"
+#include "matrixmath.h"
+#include "extendedmatrix.h"
+#include "MemoryManager.h"
+#include "spnbox.h"
+
+static int CheckParams(matrix* Dm, matrix* Dp, int** X, int* XCount, matrix *Dcm, matrix *Dcp, int update);
+
+static int isUnique(matrix* D, int* X, int XCount);
+
+static actn_r BuildResult(matrix* Dm, matrix* Dp, int* cullPlace, int* cullTrans);
+
+static int* cullPlaces(matrix* Dp, int* cullTransition);
+
+static int* updateURT(matrix* Dm, matrix* Dp, matrix* Dcm, matrix* Dcp);
+
+static int CheckParams(matrix* Dm, matrix* Dp, int** X, int* XCount, matrix *Dcm, matrix *Dcp, int update);
+
+actn_r actn(matrix* Dm, matrix* Dp, int* X, int XCount, matrix *Dcm, matrix *Dcp, int update, int checkUnique)
+{
+ actn_r result;
+ nltrans_r nltransResult;
+ MemoryManager memory;
+ matrix D; /*The incidence matrix*/
+ int *cullTransition; /*An array of flags, one for each transition, set if it
+ should be culled (is unraisable)*/
+ int *cullPlace; /*An array of flags, one for each place, set if the place
+ should be culled.*/
+
+ /*Initialize the error return value*/
+ memset(&result, 0, sizeof(actn_r));
+
+ /*Initialize the memory manager*/
+ memory = CreateMemoryManager(5, 5, 0, 0);
+
+ /*Check the parameters.*/
+ if (! CheckParams(Dm, Dp, &X, &XCount, Dcm, Dcp, update)) return result;
+
+ /*Get the incidence matrix - we'll need it later.*/
+ D = SubtractMatrix(Dp, Dm, (matrix*) 2);
+ ManageMatrix(&memory, &D);
+
+ if (update)
+ {
+ /*If we are in update mode, use the updateURT function to get the
+ unraisable transitions.*/
+ cullTransition = updateURT(Dm, Dp, Dcm, Dcp);
+ }
+ else
+ {
+ /*Otherwise, use nltrans to get the list of unraisable transitions.*/
+ nltransResult = nltrans(&D, X, XCount);
+ if (! (nltransResult.dtrCount))
+ {
+ /*If the call failed, fail.*/
+ FreeMemory(&memory);
+ merror(0, "ACTN: nltrans call failed");
+ return result;
+ }
+ else
+ {
+ cullTransition = nltransResult.dtr;
+ }
+ }
+ ManageMemory(&memory, cullTransition);
+
+ /*Build the cullPlace flags, which will be cleared only for places that
+ have nonzero input arcs from transitions that are not being culled.*/
+ cullPlace = cullPlaces(Dp, cullTransition);
+ ManageMemory(&memory, cullPlace);
+
+ /*Build the final output.*/
+ result = BuildResult(Dm, Dp, cullPlace, cullTransition);
+
+ /*Do an isUnique test only if the checkUnique flag is set, since the test
+ does several linear programming problems and is thus rather slow.*/
+ if (checkUnique)
+ {
+ result.unique = isUnique(&D, X, XCount);
+ }
+
+ /*Clean up.*/
+ FreeMemory(&memory);
+
+ return result;
+}
+
+/*******************************************************************************
+isUnique examines the petri net and the given set of unraisable transitions to
+determine if the live subnet that will be returned is unique. It is only called
+when the actn caller requests it.*/
+int isUnique(matrix* D, int* X, int XCount)
+{
+ /*We will be doing a linear programming problem for each raisable transition.
+ The constraint matrix will be the subset of D having only the columns
+ corresponding to transitions not in X, with a row of 1s concatenated onto the
+ bottom, and the column corresponding to whichever transition is currently
+ being tested removed (or in this case, zeroed).*/
+ matrix Dx, dx;
+ int i, j, Transitions = 0;
+ int* UnraisableT;
+ double* B;
+ short int *IntList;
+ ipsolve_r result;
+
+ //If no transitions are being evaluated, return true.
+ if ((Transitions = NumberOfColumns(*D) - XCount) <= 0) return 1;
+ /*Build a flag array of the columns whose indices are in X.*/
+ UnraisableT = tcalloc(NumberOfColumns(*D), sizeof(int));
+ for (i = 0; i < XCount; i++)
+ {
+ UnraisableT[X[i]] = 1;
+ }
+ /*Build Dx. It should include only columns of D whose indices are not in X.
+ It should be optimized for column ops.*/
+ AllocateMatrixType(2, &Dx, Transitions, NumberOfRows(*D) + 1);
+ TransposeMatrix(&Dx);
+ j = 0;
+ for (i = 0; i < NumberOfColumns(*D); i++)
+ {
+ if (! UnraisableT[i])
+ {
+ /*Fill in the last row.*/
+ SetMatrixEl(&Dx, NumberOfRows(*D), j, 1);
+ /*Fill in the other rows*/
+ CopyBlock(NumberOfRows(*D), 1, D, 0, i, &Dx, 0, j++);
+ }
+ }
+ //We are done with the flag array. Free memory.
+ free(UnraisableT);
+
+ /*Allocate space to record the values of the current column while it is
+ zeroed. Make it a type-2 transpose to optimize the column-swap operation.*/
+ AllocateMatrixType(1, &dx, 1, NumberOfRows(*D) + 1);
+ TransposeMatrix(&dx);
+
+ /*Build B. It is all zeroes except for a 1 in the last element.*/
+ B = tcalloc(NumberOfRows(*D) + 1, sizeof(double));
+ B[NumberOfRows(*D)] = 1;
+
+ /*IntList needs to be all zeroes to override the default of all 1s.*/
+ IntList = tcalloc(Transitions, sizeof(short int));
+
+ /*Iterate through each transition*/
+ for (i = 0; i < Transitions; i++)
+ {
+ /*If there is a previous transition to restore, restore it.*/
+ if (i) SwapColumns(&Dx, &dx, i - 1, 0);
+ /*Swap out the current transition. Because dx is a column of zeros this
+ will effectively zero the current transition and save a copy in dx for later
+ restoration.*/
+ SwapColumns(&Dx, &dx, i, 0);
+
+ //ipsolve_r ipsolve(matrix* L, double* B, double* f, short int *IntList, double *ub, double *lb, short int *ctype);
+ result = ipsolve(&Dx, B, 0, IntList, 0, 0, 0);
+ if (result.res) free(result.res);
+
+ /*If we get a valid solution, then free memory and return false.*/
+ if (! strcmp(result.mhow, HOW_OK))
+ {
+ free(IntList);
+ free(B);
+ DeallocateMatrix(&Dx);
+ DeallocateMatrix(&dx);
+ return 0;
+ }
+ }
+ //If we get through all transition without returning false, return true.
+ free(IntList);
+ free(B);
+ DeallocateMatrix(&Dx);
+ DeallocateMatrix(&dx);
+ return 1;
+}
+
+/*******************************************************************************
+BuildResult takes the list of places and transitions to cull from the total net
+and builds the active subnet. It returns the result structure that will be
+returned by actn.
+*/
+actn_r BuildResult(matrix* Dm, matrix* Dp, int* cullPlace, int* cullTrans)
+{
+ int Places = 0, Transitions = 0, i, j, k, l;
+ actn_r result;
+
+ /*All matrices are zeroed initially.*/
+ memset(&result, 0, sizeof(actn_r));
+
+ /*Count the number of places and transitions that are going to be left after
+ culling.*/
+ for (i = 0; i < NumberOfRows(*Dm); i++)
+ {
+ if (! cullPlace[i]) Places++;
+ }
+ for (i = 0; i < NumberOfColumns(*Dm); i++)
+ {
+ if (! cullTrans[i]) Transitions++;
+ }
+
+ /*Allocate space. Dma/Dmp are the same size as the original matrices but
+ contain only elements in non-culled rows and columns. Dmra/Dpra contain only
+ non-culled rows and columns. TA holds the indices of kept transitions.*/
+ if (Places && Transitions)
+ {
+ AllocateMatrixType(2, &result.Dmra, Places, Transitions);
+ AllocateMatrixType(2, &result.Dpra, Places, Transitions);
+ }
+ AllocateMatrixType(2, &result.Dma, NumberOfRows(*Dm), NumberOfColumns(*Dm));
+ AllocateMatrixType(2, &result.Dpa, NumberOfRows(*Dm), NumberOfColumns(*Dm));
+ result.TA = tcalloc(Transitions, sizeof(int));
+ result.TACount = Transitions;
+ /*Do the copy. k and l indicate the row and column numbers in the Dmra/Dpra
+ matrices. Fill in TA while we're at it.*/
+ l = 0;
+ for (j = 0; j < NumberOfColumns(*Dm); j++)
+ {
+ if (cullTrans[j]) continue;
+ k = 0;
+ for (i = 0; i < NumberOfRows(*Dm); i++)
+ {
+ if (cullPlace[i]) continue;
+ SetMatrixEl(&result.Dma, i, j, GetMatrixEl(Dm, i, j));
+ SetMatrixEl(&result.Dpa, i, j, GetMatrixEl(Dp, i, j));
+ SetMatrixEl(&result.Dmra, k, l, GetMatrixEl(Dm, i, j));
+ SetMatrixEl(&result.Dpra, k, l, GetMatrixEl(Dp, i, j));
+ k++;
+ }
+ result.TA[l] = j;
+ l++;
+ }
+ return result;
+}
+/*******************************************************************************
+cullPlaces examines the Petri net and the list of transitions to cull and
+returns an array of integer flags, one for each place, indicating whether that
+place should be culled.
+*/
+int* cullPlaces(matrix* Dp, int* cullTransition)
+{
+ int i, j;
+ int *cull;
+ /*Allocate and initialize the return value cull. It will be clear only for
+ places that have nonzero output arcs to transitions that are not being
+ culled.*/
+ cull = tcalloc(NumberOfRows(*Dp), sizeof(int));
+ for (i = 0; i < NumberOfRows(*Dp); i++)
+ {
+ /*Look to see if the current place has any nonzero output arcs to
+ transitions not being culled.*/
+ for (j = 0; j < NumberOfColumns(*Dp); j++)
+ {
+ if (GetMatrixEl(Dp, i, j) && (! cullTransition[j]))
+ {
+ break;
+ }
+ }
+ /*If there were no nonzero output arcs set the place flag.*/
+ if (j == NumberOfColumns(*Dp))
+ {
+ cull[i] = 1;
+ }
+ }
+ return cull;
+}
+
+/*******************************************************************************
+updateURT examines the Petri net and the predefined active subnet if given and
+returns an array of transitions that are unraisable given the active subnet.
+This is used to determine transitions to cull if in update mode.
+*/
+int* updateURT(matrix* Dm, matrix* Dp, matrix* Dcm, matrix* Dcp)
+{
+ /*This function builds a list of unraisable transitions in Dm/Dp by examining
+ Dcm/Dcp.*/
+ int Places, Transitions, SubPlaces, SubTransitions, i, j, keepGoing;
+ /*These are each flag arrays set to indicate live places or transitions at
+ various times throughout the algorithm.*/
+ int *URT, *Trans = 0, *Place = 0;
+
+ Places = NumberOfRows(*Dm);
+ Transitions = NumberOfColumns(*Dm);
+ SubPlaces = NumberOfRows(*Dcm);
+ SubTransitions = NumberOfColumns(*Dcm);
+
+ /*URT is the return value. It has a flag for each transition.*/
+ URT = tcalloc(Transitions, sizeof(int));
+ /*Trans and Place both have flags only for each of the possible new
+ transitions or places that can be added.*/
+ if (Places - SubPlaces)
+ {
+ Place = tcalloc(Places - SubPlaces, sizeof(int));
+ }
+ if (Transitions - SubTransitions)
+ {
+ Trans = tcalloc(Transitions - SubTransitions, sizeof(int));
+ }
+
+ /*URT is a flag vector with an element for each transition. It is initially
+ cleared only for non-null columns of Dcm/Dcp, where column numbers in Dcm/Dcp
+ map to the same column numbers in Dm/Dp.*/
+ for (i = 0; i < SubTransitions; i++)
+ {
+ /*See if the current column of Dcm/Dcp is non-null.*/
+ for (j = 0; j < SubPlaces; j++)
+ {
+ if (GetMatrixEl(Dcm, j, i) || GetMatrixEl(Dcp, j, i))
+ {
+ break;
+ }
+ }
+ /*If it was null, set the URT flag.*/
+ if (j == SubPlaces)
+ {
+ URT[i] = 1;
+ }
+ }
+ /*Fill the additional elements of URT, the ones not taken care of above.*/
+ for (i = SubTransitions; i < Transitions; i++)
+ {
+ URT[i] = 1;
+ }
+
+ /*Now, we loop. For the first iteration we have to do something special. Use
+ keepGoing = -1 to indicate first loop iteration.*/
+ keepGoing = -1;
+ do
+ {
+ /*The place flag should be set for any place (in Dm/Dp beyond those mapped
+ to by Dcm/Dcp) such that the place has at least one nonzero output arc to
+ a transition that is flagged in the current transition list. It should
+ be cleared for every other place. On the first loop iteration, rather
+ than using the current transition list (which maps to the columns in the
+ right of Dm/Dp that have no corresponding columns in Dcm/Dcp), we use logic
+ inverse of URT, which maps to all columns in Dm/Dp. The keepGoing flag will
+ be set to -1 on the first iteration.*/
+ memset(Place, 0, sizeof(int) * (Places - SubPlaces));
+ if (keepGoing > 0)
+ {
+ for (i = SubPlaces; i < Places; i++)
+ {
+ /*Check to see if the current place has at least one nonzero output arc
+ to a transition flagged in the current transition list.*/
+ for (j = SubTransitions; j < Transitions; j++)
+ {
+ if (Trans[j - SubTransitions] && GetMatrixEl(Dm, i, j))
+ {
+ /*If it does, set the flag and break out of the test loop.*/
+ Place[i - SubPlaces] = 1;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = SubPlaces; i < Places; i++)
+ {
+ /*Check to see if the current place has at least one nonzero output arc
+ to a transition not flagged in URT.*/
+ for (j = 0; j < SubTransitions; j++)
+ {
+ if ((! URT[j]) && GetMatrixEl(Dm, i, j))
+ {
+ /*If it does, set the flag and break out of the test loop.*/
+ Place[i - SubPlaces] = 1;
+ break;
+ }
+ }
+ }
+ }
+ /*Similarly, the transition flag should be set for any transition in Dm/Dp
+ beyond those mapped to by Dcm/Dcp such that the transition has at least one
+ nonzero input arc to a place that is flagged in the current place list.
+ Additionally, we clear every flag of URT that corresponds to a
+ transition whose flag is set in Trans. Finally, the overall loop will
+ continue only until Trans is entirely empty. Set the keepGoing flag
+ if any element of Trans is set.*/
+ keepGoing = 0;
+ memset(Trans, 0, sizeof(int) * (Transitions - SubTransitions));
+ for (j = SubTransitions; j < Transitions; j++)
+ {
+ for (i = SubPlaces; i < Places; i++)
+ {
+ if (Place[i - SubPlaces] && GetMatrixEl(Dp, i, j))
+ {
+ Trans[j - SubTransitions] = 1;
+ /*Clear the appropriate URT flag.*/
+ URT[j] = 0;
+ /*Set the keepGoing flag.*/
+ keepGoing = 1;
+ break;
+ }
+ }
+ }
+ } while (keepGoing);
+ /*Free memory*/
+ if (Place) free(Place);
+ if (Trans) free(Trans);
+ /*Return*/
+ return URT;
+}
+
+/*******************************************************************************
+CheckParams checks the parameters to make sure required parameters are present,
+checks some basic validity, and makes sure that all array pointers are null if
+their counts are zero and vice-versa.*/
+int CheckParams(matrix* Dm, matrix* Dp, int** X, int* XCount, matrix *Dcm, matrix *Dcp, int update)
+{
+ int Rows0, Cols0, Rows1, Cols1;
+ /*Dm and Dp are required and must be the same size.*/
+ if (! (Dm && Dp))
+ {
+ merror(0, "ACTN: Dm or Dp was not given");
+ return 0;
+ }
+ Rows0 = NumberOfRows(*Dm);
+ Cols0 = NumberOfColumns(*Dm);
+ if (Rows0 != NumberOfRows(*Dp) || Cols0 != NumberOfColumns(*Dp))
+ {
+ merror(0, "ACTN: The dimensions of Dm and Dp do not match");
+ return 0;
+ }
+
+ /*X is not required. Make sure that XCount is zero if X is null and vice-
+ versa.*/
+ if (! *X)
+ {
+ *XCount = 0;
+ }
+ else if (! *XCount)
+ {
+ *X = 0;
+ }
+
+ /*If update is nonzero, Dcm and Dcp are required. They cannot be larger than
+ Dm/Dp in either dimension and they must be the same size.*/
+ if (update)
+ {
+ if (! (Dcm && Dcp))
+ {
+ merror(0, "ACTN: Dcm or Dcp was not given while update was nonzero");
+ return 0;
+ }
+ Rows1 = NumberOfRows(*Dcm);
+ Cols1 = NumberOfColumns(*Dcm);
+ if (NumberOfRows(*Dcp) != Rows1 || NumberOfColumns(*Dcp) != Cols1)
+ {
+ merror(0, "ACTN: Dcm and Dcp are not the same size");
+ return 0;
+ }
+ if (Rows1 > Rows0 || Cols1 > Cols0)
+ {
+ merror(0, "ACTN: Dcm and Dcp are larger than Dm and Dp");
+ return 0;
+ }
+ }
+ return 1;
+}
Added: 2009_version/spnbox09/admcon.c
===================================================================
--- 2009_version/spnbox09/admcon.c (rev 0)
+++ 2009_version/spnbox09/admcon.c 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,613 @@
+#include <stdlib.h>
+#include "../pnheaders/general.h"
+#include "../pnheaders/matrix.h"
+#include "MemoryManager.h"
+#include "matrixmath.h"
+#include "extendedmatrix.h"
+#include "spnbox.h"
+
+static int CheckParams(admcon_p *params);
+static int GetRowCount(admcon_p *params);
+static matrix BuildZ(admcon_p *params);
+static matrix BuildDX(admcon_p *p, matrix *Z);
+static int *nlplace(admcon_p *p, matrix *DX, int *pCount);
+static ipsolve_r RawSolution(admcon_p *param, matrix *DX, int* p, int pCount);
+static admcon_r BuildResult(ipsolve_r *lpresult, int *p, int pCount, int rowCount);
+
+admcon_r admcon(admcon_p *params)
+{
+ /*Initialize to an error value.*/
+ admcon_r result;
+ memset(&result, 0, sizeof(result));
+
+ /*Check parameters.*/
+ if (! CheckParams(params))
+ {
+ return result;
+ }
+
+ /*Initialize the result to a default value.*/
+ result.how = 1;
+
+ /*Get the row count and the intermediate matrix Z.*/
+ int rowCount = GetRowCount(params);
+ matrix Z = BuildZ(params);
+ /*Get the intermediate linear programming matrix DX. Z will be deallocated
+ by the function call. If DX returns an empty matrix, it means that the
+ default solution, a copy of the siphon, is feasible. Return immediately.*/
+ matrix DX = BuildDX(params, &Z);
+ if (! DX.type)
+ {
+ /*Build the result and return. l should be a copy of the siphon vector.*/
+ result.l = tcalloc(NumberOfRows(params->Dm), sizeof(int));
+ result.lCount = NumberOfRows(params->Dm);
+ memcpy(result.l, params->siphon, sizeof(int) * NumberOfRows(params->Dm));
+ return result;
+ }
+
+ /*Get p, a list of places. This function is an aggregate of the nlplace function
+ present in the Matlab version of this function, and several lines of code
+ immediately after it. If nlplace returns a null pointer, it means that no
+ feasible solution exists.*/
+ int pCount;
+ int *p;
+ if (! (p = nlplace(params, &DX, &pCount)))
+ {
+ result.how = 0;
+ DeallocateMatrix(&DX);
+ return result;
+ }
+
+ /*Otherwise, proceed to build and solve another linear programming problem
+ using p. This problem deallocates DX.*/
+ ipsolve_r lpresult = RawSolution(params, &DX, p, pCount);
+
+ /*Get the new solution.*/
+ return BuildResult(&lpresult, p, pCount, rowCount);
+}
+
+/*******************************************************************************
+This function processes the solution returned by RawSolution to build the new
+solution. It also deallocates everything that still needs to be deallocated.*/
+admcon_r BuildResult(ipsolve_r *lpresult, int *p, int pCount, int rowCount)
+{
+ int i;
+ admcon_r result;
+
+ /*If the lp solution is valid, copy the appropriate values to the result.
+ Otherwise leave it blank.*/
+ if (! strcmp(lpresult->mhow, HOW_OK))
+ {
+ result.l = tcalloc(rowCount, sizeof(int));
+ result.lCount = rowCount;
+ for (i = 0; i < pCount; i++)
+ {
+ result.l[p[i]] = (int) lpresult->res[p[i]];
+ }
+ result.how = 1;
+ }
+ else
+ {
+ memset(&result, 0, sizeof(admcon_r));
+ }
+
+ /*Deallocate p and the lpresult.*/
+ free(p);
+ DeallocateIpsolve(lpresult);
+ return result;
+}
+
+/*******************************************************************************
+This function builds and solves a linear programming problem to get the modified
+solution vector l. It returns the raw ipsolve results - not the processed
+version that is the final solution. It also deallocates DX, which is not used
+after this point.*/
+ipsolve_r RawSolution(admcon_p *param, matrix *DX, int* p, int pCount)
+{
+ MemoryManager mem;
+ mem = CreateMemoryManager(3, 1, 0, 0);
+ /*The constraint matrix is an identity followed below by those columns
+ of DX which have indices present in p. We will do this by adding rows directly
+ to DX (it has been optimized for row ops), nulling out the columns we are not
+ interested in, and putting in 1s for the identity where we are interested.*/
+ InsertNullRows(DX, 0, pCount, -1);
+ ManageMatrix(&mem, DX);
+
+ /*Insert the 1s we are interested in. While doing it, build a flag array that
+ is set at each index present in p.*/
+ int *pFlag = mcalloc(&mem, NumberOfColumns(*DX), sizeof(int));
+ int i, j;
+ for (i = 0; i < pCount; i++)
+ {
+ pFlag[p[i]] = 1;
+ SetMatrixEl(DX, i, p[i], 1);
+ }
+ /*Now go back and zero all the columns not flagged in pFlag.*/
+ for (i = 0; i < NumberOfColumns(*DX); i++)
+ {
+ if (! pFlag[i]) MakeZeroColumn(DX, i);
+ }
+
+ /*The constraint vector should be 1s for each row that was added by the
+ identity and zeros for all elements thereafter except the last.*/
+ double *B = mcalloc(&mem, NumberOfRows(*DX), sizeof(double));
+ for (i = 0; i < pCount; i++)
+ {
+ B[i] = 1;
+ }
+ B[NumberOfRows(*DX) - 1] = 1;
+
+ /*Cost should have, for each place indexed in p, an element that is the sum
+ of all elements of Dm for that place that correspond to elements of the
+ incidence matrix D that are negative.*/
+ double *F = mcalloc(&mem, NumberOfColumns(*DX), sizeof(double));
+ for (i = 0; i < pCount; i++)
+ {
+ for (j = 0; j < NumberOfColumns(param->Dm); j++)
+ {
+ int dm = GetMatrixEl(¶m->Dm, p[i], j);
+ int dp = GetMatrixEl(¶m->Dp, p[i], j);
+ if (dp - dm < 0) F[p[i]] += (double) dm;
+ }
+ }
+
+ /*Solve the problem.*/
+ ipsolve_r result = ipsolve(DX, B, F, 0, 0, 0, 0);
+
+ /*Free memory and return the solution.*/
+ FreeMemory(&mem);
+ return result;
+}
+
+/*******************************************************************************
+Get the list of places p that are live. Return the list length in the integer
+pointed to by parameter pCount.*/
+int *nlplace(admcon_p *p, matrix *DX, int *pCount)
+{
+ MemoryManager mem;
+ mem = CreateMemoryManager(4, 1, 0, 0);
+
+ /*We need to build a linear programming problem. We will iterate through each
+ column, adjust the problem slightly, and resolve it.*/
+
+ /*We need to know how many places are flagged in the siphon flag array.*/
+ int placeCount = 0, i, j, k;
+ for (i = 0; i < NumberOfRows(p->Dm); i++)
+ {
+ if (p->siphon[i]) placeCount++;
+ }
+
+ /*The constraint matrix is the columns (?) of DX for which flags are set in the
+ siphon listing, followed to the right by a negative identity, then below by a
+ vector which will change from iteration to iteration.*/
+ matrix L;
+ MAllocateMatrixType(&mem, 2, &L, NumberOfRows(*DX) + 1, placeCount + NumberOfRows(*DX));
+ j = 0;
+ /*Copy the appropriate columns of DX.*/
+ for (i = 0; i < NumberOfRows(p->Dm); i++)
+ {
+ if (p->siphon[i])
+ {
+ CopyBlock(NumberOfRows(*DX), 1, DX, 0, i, &L, 0, j++);
+ }
+ }
+ /*Fill in the negative identity.*/
+ for (i = 0; i < NumberOfRows(*DX); i++)
+ {
+ SetMatrixEl(&L, i, i + placeCount, -1);
+ }
+
+ /*The constraint vector should be all zeros except the last element, which
+ should be 1.*/
+ double *B = mcalloc(&mem, NumberOfRows(L), sizeof(double));
+ B[NumberOfRows(L) - 1] = 1;
+
+ /*Cost vector should be all ones.*/
+ double *F = mcalloc(&mem, NumberOfColumns(L), sizeof(double));
+ for (i = 0; i < NumberOfColumns(L); i++)
+ {
+ F[i] = 1;
+ }
+
+ /*Constraint type should be all equalities (0) except that of the last column,
+ which should be a greater-than (1).*/
+ short *ctype = mcalloc(&mem, NumberOfRows(L), sizeof(short));
+ ctype[NumberOfRows(L) - 1] = 1;
+
+ /*IntList should be all zeroes.*/
+ short *intList = mcalloc(&mem, NumberOfColumns(L), sizeof(short));
+
+ /*During our iterations we will modify a flag array, cov, with an element for
+ each of the columns that came from DX. Allocate space.*/
+ int *cov = mcalloc(&mem, placeCount, sizeof(int));
+
+ /*Start the iterations. Store in j the index of the last column of L such that
+ its element in the last row was set to 1 within the loop. -1 means no column
+ set yet.*/
+ j = -1;
+ for (i = 0; i < placeCount; i++)
+ {
+ /*Process only columns which are not flagged yet in cov.*/
+ if (cov[i]) continue;
+
+ /*The last row of the constraint matrix should be all zeros except for the
+ element corresponding to the current column, which should be 1.*/
+ if (j >= 0) SetMatrixEl(&L, NumberOfRows(L) - 1, j, 0);
+ j = i;
+ SetMatrixEl(&L, NumberOfRows(L) - 1, i, 1);
+
+ /*Solve the linear programming problem. Let the bounds default to 0 and inf.*/
+ ipsolve_r lpresult = ipsolve(&L, B, F, intList, 0, 0, ctype);
+
+ /*If the solution is valid, set any elements of cov for which there is a
+ nonzero (and not very small) value in the solution vector.*/
+ if (! strcmp(lpresult.mhow, HOW_OK))
+ {
+ for (k = 0; k < placeCount; k++)
+ {
+ if (lpresult.res[k] > HOW_MAX_ERROR || lpresult.res[k] < -HOW_MAX_ERROR)
+ {
+ cov[k] = 1;
+ }
+ }
+ }
+ /*Deallocate any memory used by the solution.*/
+ DeallocateIpsolve(&lpresult);
+ }
+
+ /*Build the result. It is a list of the indices of elements of the siphon list
+ (places) that correspond to nonzero elements in cov. Start by counting them.*/
+ *pCount = 0;
+ for (i = 0; i < placeCount; i++)
+ {
+ if (cov[i]) (*pCount)++;
+ }
+ /*Allocate space and do the building. Each index should be not the index
+ within cov, but, for the ith element of cov, the index of the ith nonzero
+ element in siphon. Use j to count indices in siphon.*/
+ int *result = tcalloc(*pCount, sizeof(int));
+ j = -1;
+ k = 0;
+ for (i = 0; i < placeCount; i++)
+ {
+ /*Find the ith nonzero place in siphon.*/
+ j++;
+ while (! p->siphon[j]) j++;
+ /*If the current nonzero place is flagged in cov, copy the index.*/
+ if (cov[i]) result[k++] = j;
+ }
+ /*Free up memory.*/
+ FreeMemory(&mem);
+
+ /*Make sure that there are at least two places with indices in p that are
+ also present in the active place list. Count places like that in k.*/
+ k = 0;
+ for (i = 0; i < *pCount; i++)
+ {
+ for (j = 0; j < p->apCount; j++)
+ {
+ if (result[i] == p->apl[j])
+ {
+ if (++k == 2) break;
+ }
+ }
+ }
+ /*If not, no feasible solution to the admcon problem exists. Return a null
+ pointer to indicate this.*/
+ if (k < 2)
+ {
+ free(result);
+ *pCount = 0;
+ return 0;
+ }
+ return result;
+}
+
+/*******************************************************************************
+This function builds the intermediate linear programming description matrix DX.
+It runs a test on DX, and if the value of l (the solution vector) is already
+correct it returns an empty matrix to signify that admcon should return
+immediately. This function also deallocates the Z matrix, which, is not used
+again.*/
+matrix BuildDX(admcon_p *p, matrix *Z)
+{
+ /*DX is a matrix composed of a right-to-left concatentation of submatrices, all transposed:
+ DX = [Auc, Auo, -Auo, -Ds, d]'
+ For:
+ Auc = Z * DI(:,Tuc)
+ Auo = Z * DI(:,Tuo)
+ Ds = (Dp - Dm)(:,ntr) %that is, the part of the incidence matrix corresponding
+ %to transitions that came from transition split.
+ d = a flag array, one for each place, set to 1 for active places.
+ */
+ /*Allocate DX.*/
+ matrix DX;
+ AllocateMatrixType(2, &DX, p->TucCount + p->TuoCount + p->TuoCount + p->ntCount + 1, NumberOfRows(*Z));
+
+ int i, j, k;
+ for (i = 0; i < NumberOfColumns(DX); i++)
+ {
+ /*Fill in Auc.*/
+ for (j = 0; j < p->TucCount; j++)
+ {
+ SetMatrixEl(&DX, j, i, MultiplyVector(Z, &p->DI, i, p->Tuc[j], 0));
+ }
+ /*Fill in Auo and -Auo.*/
+ for (j = 0; j < p->TuoCount; j++)
+ {
+ k = MultiplyVector(Z, &p->DI, i, p->Tuo[j], 0);
+ SetMatrixEl(&DX, j + p->TucCount, i, k);
+ SetMatrixEl(&DX, j + p->TucCount + p->TuoCount, i, -k);
+ }
+ /*Fill in -Ds.*/
+ for (j = 0; j < p->ntCount; j++)
+ {
+ k = GetMatrixEl(&p->Dm, i, p->ntr[j]) - GetMatrixEl(&p->Dp, i, p->ntr[j]);
+ SetMatrixEl(&DX, j + p->TucCount + (2 * p->TuoCount), i, k);
+ }
+ }
+ /*Fill in d.*/
+ for (i = 0; i < p->apCount; i++)
+ {
+ SetMatrixEl(&DX, NumberOfRows(DX) - 1, p->apl[i], 1);
+ }
+ /*Deallocate Z. It will not be needed anymore.*/
+ DeallocateMatrix(Z);
+
+ /*Run a test. If DX * siphon (the default solution vector is simply the siphon)
+ >= b, the default solution vector is good. b should be a vector of all zeros
+ except for the last element, which should be 1. We can skip the building of b
+ and simply put the test in a loop.*/
+ if (p->siphon)
+ {
+ for (i = 0; i < NumberOfRows(DX); i++)
+ {
+ k = MultiplyVector(&DX, (matrix*) p->siphon, i, MULTIPLYVECTOR_ARRAY, 0);
+ if (k < (i < NumberOfRows(DX) - 1 ? 0 : 1))
+ {
+ break;
+ }
+ }
+ /*If we made it through the loop without breaking out early, it means that the
+ default solution vector is valid. Deallocate and zero DX and return to
+ indicate this. Otherwise just return DX as-is for the next stage in
+ processing.*/
+ if (i == NumberOfRows(DX))
+ {
+ DeallocateMatrix(&DX);
+ }
+ }
+ return DX;
+}
+
+/*******************************************************************************
+This function builds the matrix Z, an intermediate matrix of the admcon
+algorithm.*/
+matrix BuildZ(admcon_p *p)
+{
+ /*Build the independent place flag array. This is an array of flags, one for
+ each element of the independent place list. The flag should be set of the
+ place indexed by the corresponding ind. place list element is also present in
+ the original place list.*/
+ int *ipFlag = 0;
+ int ipFlagged = 0, i, j, k;
+ if (p->ipl)
+ {
+ ipFlag = tcalloc(p->ipCount, sizeof(int));
+ for (i = 0; i < p->ipCount; i++)
+ {
+ for (j = 0; j < p->opCount; j++)
+ {
+ if (p->ipl[i] == p->opl[j])
+ {
+ ipFlag[i] = 1;
+ ipFlagged++;
+ break;
+ }
+ }
+ }
+ }
+
+ /*Initialize the result to an empty matrix.*/
+ matrix result;
+ memset(&result, 0, sizeof(matrix));
+
+ if (ipFlagged)
+ {
+ /*Allocate space for Z.*/
+ AllocateMatrixType(2, &result, p->ipCount + p->dpCount, ipFlagged);
+ j = 0;
+ /*Build Z. We'll need to examine each independent place.*/
+ for (i = 0; i < p->ipCount; i++)
+ {
+ if (ipFlag[i])
+ {
+ /*Build the part of Z based on independent places. We are inserting an
+ identity, except that some columns (those not flagged in ipFlagged) must
+ be removed premptively. Thus, on the ith independent place, count how
+ many places up to that point have been flagged. Use j. Set the jth
+ column of Z (at the appropriate row) to a 1.*/
+ SetMatrixEl(&result, p->ipl[i], j, 1);
+
+ /*Build the part of Z based on dependent places. We are copying rows
+ from M to their corresponding rows in Z (dep. place rows) except that
+ the columns not flagged in ipFlag will not be copied.*/
+ if (p->M.type)
+ {
+ for (k = 0; k < p->dpCount; k++)
+ {
+ SetMatrixEl(&result, p->dpl[k], j, GetMatrixEl(&p->M, k, i));
+ }
+ }
+
+ j++;
+ }
+ }
+ }
+ /*Free the flag array.*/
+ if (ipFlag) free(ipFlag);
+ return result;
+}
+
+/*******************************************************************************
+This function gets the row count.*/
+int GetRowCount(admcon_p *params)
+{
+ int max = 0, i;
+ for (i = 0; i < params->ipCount; i++)
+ {
+ if (params->ipl[i] > max) max = params->ipl[i];
+ }
+ for (i = 0; i < params->dpCount; i++)
+ {
+ if (params->dpl[i] > max) max = params->dpl[i];
+ }
+ for (i = 0; i < params->opCount; i++)
+ {
+ if (params->opl[i] > max) max = params->opl[i];
+ }
+ return max + 1;
+}
+
+/*******************************************************************************
+This function checks the parameters to make sure they are valid.*/
+int CheckParams(admcon_p *params)
+{
+ /*If the skipParamCheck flag is set, skip the checks. Return 1 immediately.*/
+ if (params->skipParamCheck) return 1;
+
+ int i, j;
+ if (! params)
+ {
+ merror(0, "ADMCON: No parameters provided");
+ return 0;
+ }
+ /*Dm and Dp must be present.*/
+ if (! (params->Dm.type && params->Dp.type))
+ {
+ merror(0, "ADMCON: Dm and Dp were not initialized");
+ return 0;
+ }
+ /*Dm and Dp must be the same size.*/
+ if (NumberOfRows(params->Dm) != NumberOfRows(params->Dp) || NumberOfColumns(params->Dm) != NumberOfColumns(params->Dp))
+ {
+ merror(0, "ADMCON: Dm and Dp are not the same size");
+ return 0;
+ }
+ /*DI must be present.*/
+ if (! params->DI.type)
+ {
+ merror(0, "ADMCON: DI has not been initialized");
+ return 0;
+ }
+ /*Make sure that array pointers are null if their counts are null.*/
+ if (! params->ipCount) params->ipl = 0;
+ else if (! params->ipl) params->ipCount = 0;
+ if (! params->dpCount) params->dpl = 0;
+ else if (! params->dpl) params->dpCount = 0;
+ if (! params->opCount) params->opl = 0;
+ else if (! params->opl) params->opCount = 0;
+ if (! params->apCount) params->apl = 0;
+ else if (! params->apl) params->apCount = 0;
+ if (! params->ntCount) params->ntr = 0;
+ else if (! params->ntr) params->ntCount = 0;
+ if (! params->TucCount) params->Tuc = 0;
+ else if (! params->Tuc) params->TucCount = 0;
+ if (! params->TuoCount) params->Tuo = 0;
+ else if (! params->Tuo) params->TuoCount = 0;
+
+ /*If the dependent/independent place lists are provided, run some tests.*/
+ if (params->ipl || params->dpl)
+ {
+ /*Their total count must be that of the total number of places.*/
+ if (params->ipCount + params->dpCount != NumberOfRows(params->Dm))
+ {
+ merror(0, "ADMCON: The number of dependent and independent places does not match the total number of places");
+ return 0;
+ }
+ /*They cannot include any of the same places or include any out-of-range
+ indices.*/
+ for (i = 0; i < params->ipCount; i++)
+ {
+ if (params->ipl[i] < 0 || params->ipl[i] > NumberOfRows(params->Dm))
+ {
+ merror(0, "ADMCON: The independent place list has an out-of-range index");
+ return 0;
+ }
+ }
+ for (i = 0; i < params->dpCount; i++)
+ {
+ if (params->dpl[i] < 0 || params->dpl[i] > NumberOfRows(params->Dm))
+ {
+ merror(0, "ADMCON: The dependent place list has an out-of-range index");
+ return 0;
+ }
+ }
+ for (i = 0; i < params->ipCount; i++)
+ {
+ for (j = 0; j < params->dpCount; j++)
+ {
+ if (params->ipl[i] == params->dpl[j])
+ {
+ merror(0, "ADMCON: The independent and dependent place lists contain common elements");
+ return 0;
+ }
+ }
+ }
+ }
+ /*If the list of transitions that resulted from the transition split is present,
+ make sure there are no duplicate or out-of-range elements.*/
+ if (params->ntr)
+ {
+ for (i = 0; i < params->ntCount; i++)
+ {
+ if (params->ntr[i] < 0 || params->ntr[i] > NumberOfColumns(params->Dm))
+ {
+ merror(0, "ADMCON: The new transition list contains an out-of-range index");
+ return 0;
+ }
+ for (j = i + 1; j < params->ntCount; j++)
+ {
+ if (params->ntr[i] == params->ntr[j])
+ {
+ merror(0, "ADMCON: The new transition list containts duplicate entries");
+ }
+ }
+ }
+ }
+ /*If M is present (nonzero) it must have the same number of columns as there
+ are independent places and the same number of rows as there are independent
+ places.*/
+ if (params->M.type && (params->ipl && params->dpl))
+ {
+ if (NumberOfColumns(params->M) != params->ipCount || NumberOfRows(params->M) != params->dpCount)
+ {
+ merror(0, "The dependent-to-independent marking transformation matrix is not the right size");
+ return 0;
+ }
+ }
+ /*At least one of Tuc or Tuo must be provided.*/
+ if (! (params->Tuc || params->Tuo))
+ {
+ merror(0, "ADMCON: No unobservable or uncontrollable transitions were given");
+ return 0;
+ }
+ /*Neither Tuc nor Tuo should contain duplicate or out-of-range indices.*/
+ for (i = 0; i < params->TucCount; i++)
+ {
+ if (params->Tuc[i] < 0 || params->Tuc[i] >= NumberOfColumns(params->DI))
+ {
+ merror(0, "ADMCON: Tuc contains an out-of-range index");
+ return 0;
+ }
+ }
+ for (i = 0; i < params->TuoCount; i++)
+ {
+ if (params->Tuo[i] < 0 || params->Tuo[i] >= NumberOfColumns(params->DI))
+ {
+ merror(0, "ADMCON: Tuo contains an out-of-range index");
+ return 0;
+ }
+ }
+ return 1;
+}
Added: 2009_version/spnbox09/asiph.c
===================================================================
--- 2009_version/spnbox09/asiph.c (rev 0)
+++ 2009_version/spnbox09/asiph.c 2011-04-08 22:36:44 UTC (rev 246)
@@ -0,0 +1,901 @@
+#include <stdio.h>
+#include "../pnheaders/general.h"
+#include "../pnheaders/matrix.h"
+#include "spnbox.h"
+#include "MemoryManager.h"
+#include "extendedmatrix.h"
+
+typedef struct asiph_data
+{
+ int *numInputPlaces;
+ int *curTrans;
+ int *counters;
+ matrix M;
+ matrix N;
+ matrix MT;
+ matrix NT;
+ matrix newRow;
+ matrix newPlace;
+ matrix MNS;
+ matrix NS;
+} asiph_data;
+
+static int CheckParams(matrix *Dm, matrix *Dp, int **list, int *listCount, matrix *PS, matrix **Dma, matrix **Dpa, MemoryManager *mem);
+static matrix SXInit(matrix *Dm, matrix *Dp, matrix *Dma, matrix* Dpa, matrix *PS, int **list, int* listCount, asiph_data* data);
+static int* insert(asiph_data* data, matrix* vector, int* index);
+static int *DataInit(matrix *Dm, matrix *Dp, matrix *PS, matrix *sx, asiph_data* data);
+static int GetNewTrans(matrix *Dm, matrix *Dp, matrix *Places, int *Flags);
+static void OuterLoopInit(asiph_data* data, matrix *Dm, matrix *Dp, MemoryManager *mem);
+static void MiddleLoopInit(asiph_data* data, asiph_r* result, int siphon);
+static void InnerLoopInit(asiph_data* data, matrix *Dm, matrix *Dp);
+static int Check1(matrix *MNS, matrix *newRow);
+static int Check2(matrix* M, matrix* newRow);
+static int* DoInnerLoop(asiph_data* data, matrix* Dm, matrix *Dp, int* index);
+static void PrintPercent(int num, int denom);
+static asiph_r BuildResult(matrix *Dm, matrix *Dp, asiph_data* data, int *index);
+
+asiph_r asiph(matrix *Dm, matrix *Dp, int* list, int listCount, matrix *PS, matrix *Dma, matrix *Dpa)
+{
+ MemoryManager mem;
+ mem = CreateMemoryManager(10, 10, 0, 0);
+ asiph_r result;
+ memset(&result, 0, sizeof(asiph_r));
+ /*Check parameters.*/
+ if (! CheckParams(Dm, Dp, &list, &listCount, PS, &Dma, &Dpa, &mem))
+ {
+ return result;
+ }
+ asiph_data data;
+ memset(&data, 0, sizeof(asiph_data));
+
+ /*Initialize sx (and a few other things)*/
+ matrix sx = SXInit(Dm, Dp, Dma, Dpa, PS, &list, &listCount, &data);
+ ManageMatrix(&mem, &sx);
+ /*Initialize some other parts of the loop data. Build the newIndex array.*/
+ int *newIndex = DataInit(Dm, Dp, PS, &sx, &data);
+
+ /*Allocate and initialize various quantities that do not change or the space
+ for which does not change over the iterations of the outer loop.*/
+ OuterLoopInit(&data, Dm, Dp, &mem);
+
+ /*Iterate through each of the rows of NS. Each row corresponds to a siphon
+ that needs to be processed. If verbosity is high enough we'll be printing a
+ progress report as we go. Prepare.*/
+ int siphon, originalSiphons;
+ originalSiphons = NumberOfRows(data.NS);
+ if (is_verbose() >= VRB_ASIPH)
+ {
+ printf("ASIPH: Primary Processing Loop Progress: ");
+ PrintPercent(0, 1);
+ }
+ for (siphon = 0; siphon < originalSiphons; siphon++)
+ {
+ /*Initialize the stuff that doesn't change within the middle loop.*/
+ MiddleLoopInit(&data, &result, siphon);
+ /*The middle loop runs until we have removed all rows from M/N*/
+ while (NumberOfRows(data.M))
+ {
+ /*Initialize the stuff for the innermost loop run.*/
+ InnerLoopInit(&data, Dm, Dp);
+ /*Run the inner loop. This has been moved to its own function.*/
+ newIndex = DoInnerLoop(&data, Dm, Dp, newIndex);
+ /*Now concatenate MT onto M and NT onto N.*/
+ if (NumberOfRows(data.MT)) InsertRows(&data.M, &data.MT, -1, -1);
+ if (NumberOfRows(data.NT)) InsertRows(&data.N, &data.NT, -1, -1);
+ /*Remove the first row of M and N.*/
+ RemoveRows(&data.M, 0, 1, -1);
+ RemoveRows(&data.N, 0, 1, -1);
+ }
+ /*Deallocate whatever still needs to be deallocated - M and N.*/
+ DeallocateMatrix(&data.M);
+ DeallocateMatrix(&data.N);
+ /*If verbosity is high enough, print a progress percentage.*/
+ if (is_verbose() >= VRB_ASIPH)
+ {
+ PrintPercent(siphon + 1, originalSiphons);
+ }
+ }
+ if (is_verbose() >= VRB_ASIPH)
+ {
+ PrintPercent(1, 1);
+ printf("\n");
+ }
+ /*If MNS is empty, build it based on if there are any source transitions.*/
+ result = BuildResult(Dm, Dp, &data, newIndex);
+ FreeMemory(&mem);
+ return result;
+}
+
+/*******************************************************************************
+This function builds the result structure.*/
+asiph_r BuildResult(matrix *Dm, matrix *Dp, asiph_data* data, int *index)
+{
+ int i, j, oFlag, iFlag, flag = 0;
+ int *sourceF;
+ sourceF = tcalloc(NumberOfColumns(*Dm), sizeof(int));
+
+ /*Build a set of source transition flags.*/
+
+ /*If MNS is empty, build a new MNS algo...
[truncated message content] |