/*
* File name: TNTMethods.java (package eas.users.lukas.tnt)
* Author(s): Lukas König
* Java version: 6.0
* Generation date: 09.09.2011 (08:47:25)
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
* author or licensor (but not in any way that suggests that they endorse
* you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
* distribute the resulting work only under the same or a similar license to
* this one.
*
* + Detailed license conditions (Germany):
* http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
* http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/
package eas.users.lukas.tnt;
import java.util.LinkedList;
import java.util.List;
import eas.users.lukas.tnt.arithmetic.Addition;
import eas.users.lukas.tnt.arithmetic.Equality;
import eas.users.lukas.tnt.arithmetic.Exists;
import eas.users.lukas.tnt.arithmetic.Multiplication;
import eas.users.lukas.tnt.propositionalCalculus.Conjunction;
import eas.users.lukas.tnt.propositionalCalculus.Disjunction;
import eas.users.lukas.tnt.propositionalCalculus.Negation;
/**
* @author Lukas König
*
*/
public class TNTMethods {
public static int FIRST_FREE_VAR_SPACE = 0;
/**
* Renames a variable in a statement by keeping the statement's meaning
* equivalent; i.e., if v2 exists in s, it is first renamed consistently
* before performing the actual renaming from v1 to v2.
*
* @param s The statement to perform the changes on.
* @param v1 The variable to rename.
* @param v2 The variable's new name.
*/
public static void renameVarConsistently(Statement s, Variable v1, Variable v2) {
if (v1.equals(v2)) {
return;
}
if (s.existsVariable(v2)) {
renameVarConsistently(s, v2, new Variable(Math.max(v1.getVarNum(), v2.getVarNum()) + 1));
}
s.renameVariable(v1, v2);
}
/**
* Renames a variable in a statement by keeping the statement's meaning
* equivalent; i.e., if v2 exists in s, it is first renamed consistently
* before performing the actual renaming from v1 to v2.
*
* @param s The statement to perform the changes on.
* @param v1 The variable to rename.
* @param v2 The variable's new name.
*/
public static void renameVarConsistently(Term t, Variable v1, Variable v2) {
if (v1.equals(v2)) {
return;
}
if (t.existsVariable(v2)) {
renameVarConsistently(t, v2, new Variable(Math.max(v1.getVarNum(), v2.getVarNum()) + 1));
}
t.renameVariable(v1, v2);
}
public static int getFirstFreeSpaceVar(List<Variable> allUsedVars) {
int firstFreeVarSpace = 0;
for (Variable v : allUsedVars) {
if (v.getVarNum() >= firstFreeVarSpace) {
firstFreeVarSpace = v.getVarNum() + 1;
}
}
return firstFreeVarSpace;
}
/**
* Performs a logical check if the two statements represent the same
* expression. This is very forbidden in pure TNT, however, for practical
* purposes it is useful here.
*
* Up to now implemented:
* - Same except for variable renames.
* - Same except for commutativity / associativity (TODO!).
*
* @param s1 One statement.
* @param s2 Another statement.
*
* @return A matched statement if the two statements represent the same
* "idea when being interpreted as statements about numbers",
* <code>null</code> otherwise.
* @throws CloneNotSupportedException
*/
public static Statement match(Statement s1, Statement s2) throws CloneNotSupportedException {
Statement matched1;
Statement matched2;
if (!s1.isStructurallyEqual(s2)) {
return null;
}
matched1 = s1.clone();
matched2 = s2.clone();
FIRST_FREE_VAR_SPACE = 0;
matched1.renameDuplicateVariables();
matched2.renameDuplicateVariables();
List<Variable> usedVars1 = cutOffDuplicates(matched1.getAllVariables());
List<Variable> usedVars2 = cutOffDuplicates(matched2.getAllVariables());
List<Variable> allUsedVars = new LinkedList<Variable>();
allUsedVars.addAll(usedVars1);
allUsedVars.addAll(usedVars2);
allUsedVars = cutOffDuplicates(allUsedVars);
int firstFreeVarSpace = 0; // The var position after the last used one.
for (Variable v : allUsedVars) {
if (v.getVarNum() >= firstFreeVarSpace) {
firstFreeVarSpace = v.getVarNum() + 1;
}
}
// Geht das nicht schneller...? (TODO)
for (int i = 0; i < usedVars1.size(); i++) {
Variable v1 = usedVars1.get(i).clone();
Variable v2 = usedVars2.get(i).clone();
if (!v1.equals(v2)) {
renameVarConsistently(matched1, v1, new Variable(firstFreeVarSpace));
usedVars1 = cutOffDuplicates(matched1.getAllVariables());
v1 = usedVars1.get(i).clone();
if (!v1.equals(v2)) {
renameVarConsistently(matched2, v2, new Variable(firstFreeVarSpace));
}
firstFreeVarSpace++;
usedVars2 = cutOffDuplicates(matched2.getAllVariables());
}
}
if (matched1.equals(matched2)) {
return matched1;
} else {
return null;
}
}
public static List<Variable> cutOffDuplicates(List<Variable> list) {
LinkedList<Variable> newlist = new LinkedList<Variable>();
for (int i = 0; i < list.size(); i++) {
Variable item = list.get(i);
if (!newlist.contains(item)) {
newlist.add(item);
}
}
return newlist;
}
@SuppressWarnings(value = { "all" })
public static void main(String[] args) throws CloneNotSupportedException {
Variable a = new Variable(0), b = new Variable(1), c = new Variable(2);
Variable d = new Variable(3), e = new Variable(4), f = new Variable(5);
Statement s1 = new Negation(new Exists(new Exists(new Exists(new Equality(new Multiplication(new Multiplication(a, a), a), new Addition(new Multiplication(new Multiplication(new Addition(b, new Number(1)), new Addition(b, new Number(1))), new Addition(b, new Number(1))), new Multiplication(new Multiplication(new Addition(c, new Number(1)), new Addition(c, new Number(1))), new Addition(c, new Number(1))))), c), b), a));
Statement s2 = s1.clone();
s1 = new Disjunction(new Conjunction(s1.clone(), s1.clone()), s1.clone());
Statement s3 = s2.clone();
renameVarConsistently(s3, a.clone(), d.clone());
renameVarConsistently(s3, b.clone(), e.clone());
renameVarConsistently(s3, c.clone(), f.clone());
s2 = new Disjunction(new Conjunction(s2.clone(), s3.clone()), s3.clone());
renameVarConsistently(s2, b, a);
System.out.println(s1);
System.out.println(s2);
System.out.println(match(s1, s2));
}
}