Commit fcba3c4f authored by Ryan Wisnesky's avatar Ryan Wisnesky
Browse files

lazy evaluation for eqs for saturated instances

parent 83529b35
......@@ -14,7 +14,7 @@ import java.util.stream.Collectors;
import catdata.aql.Term;
@SuppressWarnings("serial")
public final class Ctx<K,V> implements Serializable {
public class Ctx<K,V> implements Serializable {
public final LinkedHashMap<K,V> map;
......
......@@ -209,8 +209,12 @@ public abstract class Instance<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> implements S
if (!sks().isEmpty()) {
toString += "\n\t" + Util.sep(sks().map, " : " , "\n\t");
}
if (!eqs0.isEmpty()) {
toString += "\n\n" + w + "\n\t" + Util.sep(eqs0, "\n\t");
if (eqs().size() < 1024 * 16) {
if (!eqs0.isEmpty()) {
toString += "\n\n" + w + "\n\t" + Util.sep(eqs0, "\n\t");
}
} else {
toString += "\n\n too many to list \n\n";
}
return toString.trim();
}
......
......@@ -34,7 +34,9 @@ extends Instance<Ty, En2, Sym, Fk2, Att2, Row<En2,X>, Y, Row<En2,X>, Y>
I = i;
alg = new EvalAlgebra<>(Q, I, options);
J = new SaturatedInstance<>(alg, dp(), I.requireConsistency(), I.allowUnsafeJava(), false, null);
validate();
if (J.eqs().size() < 1024*16) {
validate();
}
}
@Override
......
package catdata.aql.fdm;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Function;
import catdata.Unit;
public class LazySet<E> implements Set<E> {
private Set<E> s;
private final Function<Unit,Set<E>> c;
private final int size;
public LazySet(Function<Unit, Set<E>> c, int size) {
this.c = c;
this.size = size;
}
@Override
public int size() {
return size;
}
private void init() {
if (s == null) {
s = c.apply(new Unit());
}
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(Object o) {
init();
return s.contains(o);
}
@Override
public Iterator<E> iterator() {
init();
return s.iterator();
}
@Override
public Object[] toArray() {
init();
return s.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
init();
return s.toArray(a);
}
@Override
public boolean add(E e) {
init();
return s.add(e);
}
@Override
public boolean remove(Object o) {
init();
return s.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
init();
return s.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends E> c) {
init();
return s.addAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
init();
return s.retainAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
init();
return s.removeAll(c);
}
@Override
public void clear() {
init();
s.clear();
}
}
......@@ -2,7 +2,12 @@ package catdata.aql.fdm;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -11,6 +16,7 @@ import catdata.Ctx;
import catdata.Null;
import catdata.Pair;
import catdata.Triple;
import catdata.Unit;
import catdata.Util;
import catdata.aql.Algebra;
import catdata.aql.Collage;
......@@ -24,7 +30,7 @@ import catdata.aql.Var;
public class SaturatedInstance<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y>
extends Instance<Ty, En, Sym, Fk, Att, X, Y, X, Y> {
private final Set<Pair<Term<Ty, En, Sym, Fk, Att, X, Y>, Term<Ty, En, Sym, Fk, Att, X, Y>>> eqs = new HashSet<>();
private final Set<Pair<Term<Ty, En, Sym, Fk, Att, X, Y>, Term<Ty, En, Sym, Fk, Att, X, Y>>> eqs; // = new HashSet<>();
private final Ctx<X, En> gens = new Ctx<>();
private final Ctx<Y, Ty> sks;
......@@ -45,52 +51,236 @@ extends Instance<Ty, En, Sym, Fk, Att, X, Y, X, Y> {
public Algebra<Ty, En, Sym, Fk, Att, X, Y, X, Y> algebra() {
return inner_alg;
}
/*
public class InnerCtx<K,V> extends Ctx<K,V> {
public <X> Ctx<K,Chc<V,X>> inLeft() {
}
public boolean containsKey(K k) {
}
public static <K,V> Pair<K,V> getOnly(Map<K,V> map) {
}
public Set<K> keySet() {
}
public Collection<V> values() {
}
public boolean isEmpty() {
}
public Ctx() {
}
public void putAll(Map<K,V> m) {
}
public void remove(K k) {
}
public Ctx(Map<K,V> map) {
}
public Ctx(List<Pair<K,V>> list) {
}
@Override
public String toString() {
return toString(Object::toString);
}
public String toString(Function<V,String> fn) {
return Util.sep(map.entrySet().stream().map(z -> z.getKey() + ":" + fn.apply(z.getValue())).collect(Collectors.toList()), ",");
}
@Override
public int hashCode() {
int prime = 31;
int result = 1;
result = prime * result + ((map == null) ? 0 : map.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Ctx<?,?> other = (Ctx<?,?>) obj;
if (map == null) {
if (other.map != null)
return false;
} else if (!map.equals(other.map))
return false;
return true;
}
public V get(K k) {
if (k == null) {
throw new RuntimeException("Attempt to lookup null key in " + map);
}
V ret = map.get(k);
if (ret == null) {
throw new RuntimeException("Attempt to lookup " + k + " failed; is not present in " + map.keySet() );
}
return ret;
}
public static <K,V> String toString(List<Pair<K, V>> ctx) {
return Util.sep(ctx.stream().map(z -> z.first + (z.second != null ? (":" + z.second) : "")).collect(Collectors.toList()), ",");
}
public void put(K k, V v) {
if (map.containsKey(k)) {
throw new RuntimeException("already contains " + k + "\n\n" + this);
}
map.put(k, v);
}
public String toString(Term<?, ?, ?, ?, ?, ?, ?> l, Term<?, ?, ?, ?, ?, ?, ?> r) {
String pre = map.isEmpty() ? "" : "forall " + Util.sep(map, ": ", ", ") + " . ";
return pre + l + " = " + r;
}
public int size() {
return map.size();
}
public <X> Ctx<K,Chc<X,V>> inRight() {
LinkedHashMap<K,Chc<X,V>> ret = new LinkedHashMap<>();
for (K k : map.keySet()) {
ret.put(k, Chc.inRight(map.get(k)));
}
return new Ctx<>(ret);
}
public <Z> Ctx<K,Z> map(Function<V, Z> f) {
Ctx<K,Z> ret = new Ctx<>();
for (K k : map.keySet()) {
ret.put(k, f.apply(get(k)));
}
return ret;
}
public <X,Y> Ctx<X,Y> map(BiFunction<K, V, Pair<X,Y>> f) {
Ctx<X,Y> ret = new Ctx<>();
for (K k : map.keySet()) {
Pair<X, Y> x = f.apply(k, get(k));
ret.put(x.first, x.second);
}
return ret;
}
public Set<Entry<K, V>> entrySet() {
return map.entrySet();
}
private boolean agreeOnOverlap0(Ctx<K, V> ret) {
for (K k : map.keySet()) {
if (ret.containsKey(k)) {
if (!ret.get(k).equals(get(k))) {
return false;
}
}
}
return true;
}
public boolean agreeOnOverlap(Ctx<K, V> ret) {
return agreeOnOverlap0(ret) && ret.agreeOnOverlap0(this);
}
public static <K,V> Ctx<K,V> fromNullable(Map<K,V> m) {
Ctx<K,V> ret = new Ctx<>();
for (K k : m.keySet()) {
if (m.get(k) != null) {
ret.put(k, m.get(k));
}
}
return ret;
}
}; */
public SaturatedInstance(Algebra<Ty, En, Sym, Fk, Att, Gen, Sk, X, Y> alg, DP<Ty, En, Sym, Fk, Att, Gen, Sk> dp, boolean requireConsistency, boolean allowUnsafeJava, boolean labelledNulls, Ctx<Y, Term<Ty, En, Sym, Fk, Att, X, Y>> reprT_extra) {
this.alg = alg;
this.dp = dp;
this.requireConsistency = requireConsistency;
this.allowUnsafeJava = allowUnsafeJava;
for (En en : schema().ens) {
for (X x : alg.en(en)) {
gens.put(x, en);
for (Att att : schema().attsFrom(en)) {
Term<Ty, En, Sym, Fk, Att, X, Y> lhs = Term.Att(att, Term.Gen(x));
if (labelledNulls) {
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = lnConv(att, x);
if (rhs == null) {
continue;
}
}
int size = 1;
for (En en : schema().ens) {
size += alg.en(en).size()*(schema().attsFrom(en).size()+schema().fksFrom(en).size());
}
final int size2 = size;
Function<Unit, Set<Pair<Term<Ty, En, Sym, Fk, Att, X, Y>, Term<Ty, En, Sym, Fk, Att, X, Y>>>> fun = _x-> {
Set<Pair<Term<Ty, En, Sym, Fk, Att, X, Y>, Term<Ty, En, Sym, Fk, Att, X, Y>>>
set = new HashSet<>(size2+2);
for (En en : schema().ens) {
for (X x : alg.en(en)) {
for (Att att : schema().attsFrom(en)) {
Term<Ty, En, Sym, Fk, Att, X, Y> lhs = Term.Att(att, Term.Gen(x));
if (labelledNulls) {
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = lnConv(att, x);
if (rhs == null) {
continue;
}
set.add(new Pair<>(lhs, rhs));
} else {
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = alg.att(att, x).convert();
set.add(new Pair<>(lhs, rhs));
}
eqs.add(new Pair<>(lhs, rhs));
} else {
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = alg.att(att, x).map(Function.identity(), Function.identity(), Util.voidFn(), Util.voidFn(), Util.voidFn(), Function.identity());
eqs.add(new Pair<>(lhs, rhs));
}
for (Fk fk : schema().fksFrom(en)) {
Term<Ty, En, Sym, Fk, Att, X, Y> lhs = Term.Fk(fk, Term.Gen(x));
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = Term.Gen(alg.fk(fk, x));
set.add(new Pair<>(lhs, rhs));
}
}
for (Fk fk : schema().fksFrom(en)) {
Term<Ty, En, Sym, Fk, Att, X, Y> lhs = Term.Fk(fk, Term.Gen(x));
Term<Ty, En, Sym, Fk, Att, X, Y> rhs = Term.Gen(alg.fk(fk, x));
eqs.add(new Pair<>(lhs, rhs));
}
for (Eq<Ty, Void, Sym, Void, Void, Void, Y> eq : alg.talg().eqs) {
if (!eq.ctx.isEmpty()) {
continue;
}
set.add(new Pair<>(eq.lhs.convert(), eq.rhs.convert()));
}
}
return set;
};
eqs = new LazySet<Pair<Term<Ty, En, Sym, Fk, Att, X, Y>, Term<Ty, En, Sym, Fk, Att, X, Y>>>(fun, size);
if (labelledNulls) {
sks = new Ctx<>();
} else {
sks = new Ctx<>(alg.talg().sks.map);
}
for (Eq<Ty, Void, Sym, Void, Void, Void, Y> eq : alg.talg().eqs) {
if (!eq.ctx.isEmpty()) {
continue;
}
eqs.add(new Pair<>(eq.lhs.map(Function.identity(), Function.identity(), Util.voidFn(), Util.voidFn(), Util.voidFn(), Function.identity()), eq.rhs.map(Function.identity(), Function.identity(), Util.voidFn(), Util.voidFn(), Util.voidFn(), Function.identity())));
}
this.reprT_extra = reprT_extra;
inner_dp = new InnerDP();
inner_alg = new InnerAlgebra();
validate();
checkSatisfaction(); //TODO aql disable in production?
if (size < 1024*16) {
validate();
checkSatisfaction(); //TODO aql disable in production?
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment