Commit 3c942e19 authored by javier's avatar javier
Browse files

added changes for expressions and semirings

parent d22a82d0
package uy.edu.fing.mina.fsa.algebra;
import uy.edu.fing.mina.fsa.tf.SimpleTf;
import uy.edu.fing.mina.fsa.tf.TfI;
final public class Matrix {
private final int M; // number of rows
private final int N; // number of columns
private final TfI[][] data; // M-by-N array
// create M-by-N matrix of 0's
public Matrix(int M, int N) {
this.M = M;
this.N = N;
data = new TfI[M][N];
}
// create matrix based on 2d array
public Matrix(TfI[][] data) {
M = data.length;
N = data[0].length;
this.data = new TfI[M][N];
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
this.data[i][j] = data[i][j];
}
// copy constructor
private Matrix(Matrix A) { this(A.data); }
// create and return the N-by-N identity matrix
public static Matrix identity(int N) {
Matrix I = new Matrix(N, N);
for (int i = 0; i < N; i++)
I.data[i][i] = SimpleTf.AcceptsAll();
return I;
}
// create and return the transpose of the invoking matrix
public Matrix transpose() {
Matrix A = new Matrix(N, M);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
A.data[j][i] = this.data[i][j];
return A;
}
// return C = A + B
public Matrix plus(Matrix B) {
Matrix A = this;
if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
Matrix C = new Matrix(M, N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
C.data[i][j] = Semiring.plus(A.data[i][j] , B.data[i][j]);
return C;
}
// does A = B exactly?
public boolean eq(Matrix B) {
Matrix A = this;
if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
if (A.data[i][j] != B.data[i][j]) return false;
return true;
}
// return C = A * B
public Matrix times(Matrix B) {
Matrix A = this;
if (A.N != B.M) throw new RuntimeException("Illegal matrix dimensions.");
Matrix C = new Matrix(A.M, B.N);
for (int i = 0; i < C.M; i++)
for (int j = 0; j < C.N; j++)
for (int k = 0; k < A.N; k++)
C.data[i][j] = Semiring.plus(C.data[i][j],Semiring.times(A.data[i][k] , B.data[k][j])) ;
return C;
}
//TODO gaussian elimination for equation solving, not sure how this translates to fst now.
/* // return x = A^-1 b, assuming A is square and has full rank
public Matrix solve(Matrix rhs) {
if (M != N || rhs.M != N || rhs.N != 1)
throw new RuntimeException("Illegal matrix dimensions.");
// create copies of the data
Matrix A = new Matrix(this);
Matrix b = new Matrix(rhs);
// Gaussian elimination with partial pivoting
for (int i = 0; i < N; i++) {
// find pivot row and swap
int max = i;
for (int j = i + 1; j < N; j++)
if (Math.abs(A.data[j][i]) > Math.abs(A.data[max][i]))
max = j;
A.swap(i, max);
b.swap(i, max);
// singular
if (A.data[i][i] == 0.0) throw new RuntimeException("Matrix is singular.");
// pivot within b
for (int j = i + 1; j < N; j++)
b.data[j][0] -= b.data[i][0] * A.data[j][i] / A.data[i][i];
// pivot within A
for (int j = i + 1; j < N; j++) {
double m = A.data[j][i] / A.data[i][i];
for (int k = i+1; k < N; k++) {
A.data[j][k] -= A.data[i][k] * m;
}
A.data[j][i] = 0.0;
}
}
// back substitution
Matrix x = new Matrix(N, 1);
for (int j = N - 1; j >= 0; j--) {
double t = 0.0;
for (int k = j + 1; k < N; k++)
t += A.data[j][k] * x.data[k][0];
x.data[j][0] = (b.data[j][0] - t) / A.data[j][j];
}
return x;
}
*/
// print matrix to standard output
public void show() {
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++)
System.out.printf("%9.4f ", data[i][j]);
System.out.println();
}
}
// test client
public static void main(String[] args) {
TfI[][] a = { { new SimpleTf("a"), new SimpleTf("b"), new SimpleTf("c") },
{ new SimpleTf("d"), new SimpleTf("e"), new SimpleTf("f") },
{ new SimpleTf("g"), new SimpleTf("h"), new SimpleTf("i")} };
Matrix A = new Matrix(a);
A.show();
System.out.println();
TfI[][] b = { { new SimpleTf("a"), new SimpleTf("b"), new SimpleTf("c") },
{ new SimpleTf("d"), new SimpleTf("e"), new SimpleTf("f") },
{ new SimpleTf("g"), new SimpleTf("h"), new SimpleTf("i")} };
Matrix B = new Matrix(b);
A.show();
System.out.println();
// A.swap(1, 2);
// A.show();
// System.out.println();
// Matrix B = A.transpose();
// B.show();
// System.out.println();
Matrix C = Matrix.identity(5);
C.show();
System.out.println();
A.plus(B).show();
System.out.println();
B.times(A).show();
System.out.println();
// shouldn't be equal since AB != BA in general
System.out.println(A.times(B).eq(B.times(A)));
System.out.println();
// Matrix b = Matrix.random(5, 1);
// b.show();
// System.out.println();
// Matrix x = A.solve(b);
// x.show();
// System.out.println();
// A.times(x).show();
}
}
\ No newline at end of file
/*______________________________________________________________________________
*
* Copyright 2005 Arnaud Bailly - NORSYS/LIFL
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* (1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* (2) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* (3) The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Created on 30 avr. 2005
*
*/
import java.util.Arrays;
/**
* Matrix representation of an automaton.
* <p>
* The elements of a the matrix are {@see SemiRing}objects.
*
* @author nono
* @version $Id: Matrix.java 6 2006-08-30 08:56:44Z oqube $
*/
public final class Matrix implements SemiRing {
/* matrices for transitions, initial and terminal states */
protected final SemiRing[][] matrix;
private int line;
private int col;
public Matrix(int ns) {
this.line = this.col = ns;
this.matrix = new SemiRing[ns][ns];
}
/**
* @param matrix
*/
public Matrix(Matrix matrix) {
this(matrix.line);
for (int i = 0; i < line; i++)
for (int j = 0; j < col; j++)
this.matrix[i][j] = matrix.matrix[i][j];
}
/**
* @param l
* @param c
*/
public Matrix(int l, int c) {
this.line = l;
this.col = c;
matrix = new SemiRing[l][c];
}
/**
* Returns the n <sup>th </sup> power of this matrix.
*
* @param n
* the power. Must be positive or null.
* @param res
* matrix where the result should be stored. Must be same size as
* this matrix with all elements initialized with null.
* @return the result Matrix object with transition matrix equals the n
* <sup>th </sup> power of this matrix's transition.
*/
public Matrix power(int n, Matrix res) {
int l = line;
if(line != col)
throw new IllegalStateException("Cannot compute power of a non square matrix");
SemiRing[][] tmp = new SemiRing[l][l];
for (int i = 0; i < l; i++)
Arrays.fill(tmp[i], matrix[0][0].zero());
for (int k = 0; k <n; k++) {
for (int i = 0; i < l; i++) {
for (int j = 0; j < l; j++) {
for (int m = 0; m < l; m++) {
if (k==0)
tmp[i][j] = tmp[i][j].plus(matrix[i][m]
.mult(matrix[m][j]));
else
tmp[i][j] = tmp[i][j].plus(res.matrix[i][m]
.mult(matrix[m][j]));
}
}
}
/* copy to res */
for (int i = 0; i < l; i++)
System.arraycopy(tmp[i],0,res.matrix[i],0,l);
}
return res;
}
/**
* Returns the star of this matrix.
*
* @return
*/
public Matrix star() {
return null;
}
public int getLine() {
return line;
}
public String toString() {
final String ln = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer();
int n = matrix.length;
for (int i = 0; i < line; i++) {
sb.append("[ ");
for (int j = 0; j < col; j++) {
String s = matrix[i][j].toString();
sb.append(s).append(' ');
}
sb.append("]").append(ln);
}
return sb.toString();
}
/* (non-Javadoc)
* @see rationals.algebra.SemiRing#plus(rationals.algebra.SemiRing)
*/
public SemiRing plus(SemiRing s2) {
if(s2 == null)
throw new IllegalArgumentException("Null argument");
Matrix o = (Matrix)s2; // maybe ClassCastException
if(col != o.col || line != o.line)
throw new IllegalArgumentException("Incompatible matrices dimensions : cannot add non square matrices");
int l = line;
int c = col;
Matrix res = Matrix.zero(l,c,matrix[0][0]);
for(int i=0;i<l;i++)
for(int j=0;j<c;j++)
res.matrix[i][j] = matrix[i][j].plus(o.matrix[i][j]);
return res;
}
/* (non-Javadoc)
* @see rationals.algebra.SemiRing#mult(rationals.algebra.SemiRing)
*/
public SemiRing mult(SemiRing s2) {
if(s2 == null)
throw new IllegalArgumentException("Null argument");
Matrix o = (Matrix)s2; // maybe ClassCastException
if(col != o.line)
throw new IllegalArgumentException("Incompatible matrices dimensions");
int l = line; // lines
int c = o.col; // cols
int m = col;
Matrix res = Matrix.zero(l,c,matrix[0][0]);
for(int i=0;i<l;i++) {
for(int j=0;j<c;j++)
for(int k=0;k<m;k++){
if(k ==0)
res.matrix[i][j] = matrix[i][k].mult(o.matrix[k][j]);
else
res.matrix[i][j] = res.matrix[i][j].plus(matrix[i][k].mult(o.matrix[k][j]));
}
}
return res;
}
/* (non-Javadoc)
* @see rationals.algebra.SemiRing#one()
*/
public SemiRing one() {
if(line != col)
throw new IllegalStateException("Cannot get unit matrix on non-square matrices");
return one(line,matrix[0][0]);
}
/* (non-Javadoc)
* @see rationals.algebra.SemiRing#zero()
*/
public SemiRing zero() {
return zero(line,col,matrix[0][0]);
}
public int getCol() {
return col;
}
/**
* Factory method for creating Matrix instances with coefficients
* in a certain SemiRing.
*
* @param sr a SemiRing instance. Used to get one and zero.
* @return a new zero matrix.
*/
public static Matrix zero(int line,int col,SemiRing sr) {
Matrix m = new Matrix(line,col);
for(int i=0;i<line;i++)
for(int j=0;j<col;j++)
m.matrix[i][j] = sr.zero();
return m;
}
/**
* Factory method for creating unit Matrix instances with coefficients
* in a certain SemiRing.
*
* @param sr a SemiRing instance. Used to get one and zero.
* @return a new unit square matrix.
*/
public static Matrix one(int dim,SemiRing sr) {
Matrix m = new Matrix(dim);
for(int i=0;i<dim;i++)
for(int j=0;j<dim;j++)
m.matrix[i][j] = (i == j) ? sr.one() : sr.zero();
return m;
}
}
package uy.edu.fing.mina.fsa.algebra;
/*______________________________________________________________________________
*
* Copyright 2005 Arnaud Bailly - NORSYS/LIFL
*
*/
/**
* An interface implemented by objects that can be coefficients of a
* Matrix.
* <p>
* A semi-ring is a structure <code>(R,+,*,0,1)</code> such that:
* <ol>
* <li><code>(R,+,0)</code> is a commutative monoid </li>
* <li><code>(R,*,1)</code> is a monoid </li>
* <li><code>x*(y+z) = x*y + x*z</code> and <code>(y+z)*x = y*x + z*x</code> : multiplication
* is distributive with respect to addition </li>
* <li><code>x*0 = 0*x = 0</code>: 0 is an absorbing element for *</li>
* </ol>
*
* @author nono
* @version $Id: SemiRing.java 2 2006-08-24 14:41:48Z oqube $
* @see Matrix
*/
public interface SemiRing {
/**
* Addition of a Semi-ring element with another element.
*
* @param s1
* @param s2
* @return
*/
public SemiRing plus(SemiRing s2);
/**
* Multiplication of semiring element with another element.
*
* @param s1
* @param s2
* @return
*/
public SemiRing mult(SemiRing s2);
/**
* Neutral element for multiplication.
*
* @return
*/
public SemiRing one();
/**
* Neutral element for addition.
*
* @return
*/
public SemiRing zero();
}
\ No newline at end of file
package uy.edu.fing.mina.fsa.test;
import uy.edu.fing.mina.fsa.tf.SimpleTf;
import uy.edu.fing.mina.fsa.tf.TfString;
import uy.edu.fing.mina.fsa.tf.Words;
import uy.edu.fing.mina.fsa.tffst.ElementOfP;
import uy.edu.fing.mina.fsa.tffst.P;
import uy.edu.fing.mina.fsa.tffst.ProtoT;
......@@ -13,13 +13,13 @@ public class LongestPrefix {
P p = new P();
TfString arriving1 = new TfString();
Words arriving1 = new Words();
arriving1.add(new SimpleTf("A"));
arriving1.add(new SimpleTf("B"));
arriving1.add(new SimpleTf("C"));
arriving1.add(new SimpleTf("D"));
TfString arriving2 = new TfString();
Words arriving2 = new Words();
arriving2.add(new SimpleTf("A"));
arriving2.add(new SimpleTf("B"));
arriving2.add(new SimpleTf("E"));
......
......@@ -4,7 +4,7 @@ import uy.edu.fing.mina.fsa.logics.Implication;
import uy.edu.fing.mina.fsa.logics.Knowledge;
import uy.edu.fing.mina.fsa.logics.Utils;
import uy.edu.fing.mina.fsa.tf.SimpleTf;
import uy.edu.fing.mina.fsa.tf.TfI;
import uy.edu.fing.mina.fsa.tf.LabelI;
public class SimplificationWithKnowledge1 {
......@@ -14,13 +14,13 @@ public class SimplificationWithKnowledge1 {
public static void main(String[] args) {
TfI r1 = new SimpleTf("r'");
TfI a1 = new SimpleTf("a'");
TfI v1 = new SimpleTf("v'");
LabelI r1 = new SimpleTf("r'");
LabelI a1 = new SimpleTf("a'");
LabelI v1 = new SimpleTf("v'");
TfI r2 = new SimpleTf("r\\\"");
TfI a2 = new SimpleTf("a\\\"");
TfI v2 = new SimpleTf("v\\\"");
LabelI r2 = new SimpleTf("r\\\"");
LabelI a2 = new SimpleTf("a\\\"");
LabelI v2 = new SimpleTf("v\\\"");
Knowledge.implications.add(new Implication(r1, a1.not()));
......
......@@ -5,7 +5,7 @@ import uy.edu.fing.mina.fsa.logics.Knowledge;
import uy.edu.fing.mina.fsa.logics.Utils;
import uy.edu.fing.mina.fsa.tf.SimpleTf;
import uy.edu.fing.mina.fsa.tf.Tf;
import uy.edu.fing.mina.fsa.tf.TfI;
import uy.edu.fing.mina.fsa.tf.LabelI;
public class SimplificationWithKnowledge2 {
......@@ -14,12 +14,12 @@ public class SimplificationWithKnowledge2 {
public static void main(String[] args) {
TfI phy = new SimpleTf("phy");
TfI man = new SimpleTf("man");
TfI rek = new SimpleTf("rek");
LabelI phy = new SimpleTf("phy");
LabelI man = new SimpleTf("man");
LabelI rek = new SimpleTf("rek");
TfI hp = new SimpleTf("hp");
TfI read = new SimpleTf("read");
LabelI hp = new SimpleTf("hp");
LabelI read = new SimpleTf("read");
Knowledge.implications.add(new Implication(Tf.createdTFs.get("man"),Tf.createdTFs.get("read")));
......
package uy.edu.fing.mina.fsa.test;
import uy.edu.fing.mina.fsa.tf.SimpleTf;
import uy.edu.fing.mina.fsa.tf.TfI;
import uy.edu.fing.mina.fsa.tf.TfString;
import uy.edu.fing.mina.fsa.tf.LabelI;
import uy.edu.fing.mina.fsa.tf.Words;