101 lines
3.0 KiB
Java
101 lines
3.0 KiB
Java
package function.builtin.predicate;
|
|
|
|
import function.ArgumentValidator;
|
|
import function.FunctionNames;
|
|
import function.LispFunction;
|
|
import sexpression.Cons;
|
|
import sexpression.SExpression;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import static function.builtin.GENSYM.GENSYM_PREFIX;
|
|
import static sexpression.Nil.NIL;
|
|
import static sexpression.Symbol.T;
|
|
|
|
@FunctionNames({ "GENSYM-EQUAL", "GENSYM-EQUAL?" })
|
|
public class GENSYM_EQUAL extends LispFunction {
|
|
|
|
private ArgumentValidator argumentValidator;
|
|
|
|
public GENSYM_EQUAL(String name) {
|
|
this.argumentValidator = new ArgumentValidator(name);
|
|
this.argumentValidator.setExactNumberOfArguments(2);
|
|
}
|
|
|
|
@Override
|
|
public SExpression call(Cons argumentList) {
|
|
argumentValidator.validate(argumentList);
|
|
|
|
Cons rest = (Cons) argumentList.getRest();
|
|
SExpression firstArgument = argumentList.getFirst();
|
|
SExpression secondArgument = rest.getFirst();
|
|
|
|
return gensymEqual(firstArgument, secondArgument);
|
|
}
|
|
|
|
private SExpression gensymEqual(SExpression firstArgument, SExpression secondArgument) {
|
|
String firstEqualized = equalizeGensyms(firstArgument);
|
|
String secondEqualized = equalizeGensyms(secondArgument);
|
|
|
|
return firstEqualized.equals(secondEqualized) ? T : NIL;
|
|
}
|
|
|
|
private String equalizeGensyms(SExpression expression) {
|
|
GensymEqualizer equalizer = new GensymEqualizer(expression.toString());
|
|
|
|
return equalizer.equalize();
|
|
}
|
|
|
|
private static class GensymEqualizer {
|
|
|
|
private static final String GENSYM_REGEX = Pattern.quote(GENSYM_PREFIX) + "[0-9]+";
|
|
|
|
Map<String, String> gensymAliases;
|
|
Matcher matcher;
|
|
String expression;
|
|
int counter;
|
|
|
|
public GensymEqualizer(String expression) {
|
|
this.gensymAliases = new HashMap<>();
|
|
this.matcher = Pattern.compile(GENSYM_REGEX).matcher(expression);
|
|
this.expression = expression;
|
|
this.counter = 0;
|
|
}
|
|
|
|
public String equalize() {
|
|
createGensymAliases();
|
|
|
|
return equalizeGensyms();
|
|
}
|
|
|
|
private void createGensymAliases() {
|
|
while (matcher.find())
|
|
createAliasForGensym();
|
|
}
|
|
|
|
private void createAliasForGensym() {
|
|
String gensym = matcher.group();
|
|
|
|
if (isNewGensym(gensym))
|
|
gensymAliases.put(gensym, GENSYM_PREFIX + (counter++));
|
|
}
|
|
|
|
private boolean isNewGensym(String gensym) {
|
|
return !gensymAliases.containsKey(gensym);
|
|
}
|
|
|
|
private String equalizeGensyms() {
|
|
String equalizedExpression = expression;
|
|
|
|
for (Entry<String, String> entry : gensymAliases.entrySet())
|
|
equalizedExpression = equalizedExpression.replace(entry.getKey(), entry.getValue());
|
|
|
|
return equalizedExpression;
|
|
}
|
|
}
|
|
}
|