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

lazy evaluation for eqs for saturated instances

parent 83529b35
Loading
Loading
Loading
Loading
+1 −1
Changes for src/catdata/Ctx.java: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -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;
	
+4 −0
Changes for src/catdata/aql/Instance.java: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -209,9 +209,13 @@ 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 (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();
	} 

+2 −0
Changes for src/catdata/aql/fdm/EvalInstance.java: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -34,8 +34,10 @@ 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);
		if (J.eqs().size() < 1024*16) {
			validate();
		}
	}

	@Override
	public Schema<Ty, En2, Sym, Fk2, Att2> schema() {
+105 −0
Changes for src/catdata/aql/fdm/LazySet.java: 105 added lines, 0 removed lines.
Original line number Diff line number Diff line
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();
	}

}
+202 −12
Changes for src/catdata/aql/fdm/SaturatedInstance.java: 202 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -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; 
	
@@ -46,14 +52,189 @@ extends Instance<Ty, En, Sym, Fk, Att, X, Y, X, Y> {
		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);
			}
		}
		
		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) {
@@ -61,36 +242,45 @@ extends Instance<Ty, En, Sym, Fk, Att, X, Y, X, Y> {
							if (rhs == null) {
								continue;
							}
						eqs.add(new Pair<>(lhs, rhs));
							set.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));
							Term<Ty, En, Sym, Fk, Att, X, Y> rhs = alg.att(att, x).convert();
							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));
				}
						set.add(new Pair<>(lhs, rhs));
					}
				}
		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())));
				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);
		}

		this.reprT_extra = reprT_extra;
		inner_dp = new InnerDP();
		inner_alg = new InnerAlgebra();
		
		if (size < 1024*16) {
			validate();
			checkSatisfaction(); //TODO aql disable in production?
		
		}		
	}