use of catdata.Quad in project fql by CategoricalData.
the class FqlppDisplay method doMappingView.
private static JComponent doMappingView(Color clr1, Color clr2, Graph<Pair, Quad> sgv) {
Layout<Pair, Quad> layout = new FRLayout<>(sgv);
layout.setSize(new Dimension(600, 400));
VisualizationViewer<Pair, Quad> vv = new VisualizationViewer<>(layout);
DefaultModalGraphMouse<String, String> gm = new DefaultModalGraphMouse<>();
gm.setMode(Mode.TRANSFORMING);
vv.setGraphMouse(gm);
gm.setMode(Mode.PICKING);
Function<Pair, Paint> vertexPaint = x -> x.second.equals("src") ? clr1 : clr2;
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
Function<Pair, String> ttt1 = arg0 -> Util.nice(arg0.first.toString());
vv.getRenderContext().setVertexLabelTransformer(ttt1);
Function<Quad, String> ttt2 = arg0 -> Util.nice(arg0.first.toString());
vv.getRenderContext().setEdgeLabelTransformer(ttt2);
float[] dash = { 1.0f };
Stroke edgeStroke = new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 10.0f);
Stroke bs = new BasicStroke();
Function<Quad, Stroke> edgeStrokeTransformer = x -> x.fourth instanceof Integer ? edgeStroke : bs;
vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);
GraphZoomScrollPane zzz = new GraphZoomScrollPane(vv);
JPanel ret = new JPanel(new GridLayout(1, 1));
ret.add(zzz);
ret.setBorder(BorderFactory.createEtchedBorder());
return ret;
}
use of catdata.Quad in project fql by CategoricalData.
the class CombinatorParser method schExpRaw.
private static Parser<SchExpRaw> schExpRaw() {
Parser<List<LocStr>> entities = Parsers.tuple(token("entities"), locstr.many()).map(x -> x.b);
Parser<Pair<Token, List<Tuple5<List<LocStr>, Token, String, Token, String>>>> fks = Parsers.tuple(token("foreign_keys"), Parsers.tuple(locstr.many1(), token(":"), ident, token("->"), ident).many());
Parser<List<catdata.Pair<LocStr, catdata.Pair<String, String>>>> fks0 = fks.map(x -> {
List<catdata.Pair<LocStr, catdata.Pair<String, String>>> ret = new LinkedList<>();
for (Tuple5<List<LocStr>, Token, String, Token, String> a : x.b) {
for (LocStr b : a.a) {
ret.add(new catdata.Pair<>(b, new catdata.Pair<>(a.c, a.e)));
}
}
return ret;
});
Parser<Pair<Token, List<Tuple5<List<LocStr>, Token, String, Token, String>>>> atts = Parsers.tuple(token("attributes"), Parsers.tuple(locstr.many1(), token(":"), ident, token("->"), ident).many());
Parser<List<catdata.Pair<LocStr, catdata.Pair<String, String>>>> atts0 = atts.map(x -> {
List<catdata.Pair<LocStr, catdata.Pair<String, String>>> ret = new LinkedList<>();
for (Tuple5<List<LocStr>, Token, String, Token, String> a : x.b) {
for (LocStr b : a.a) {
ret.add(new catdata.Pair<>(b, new catdata.Pair<>(a.c, a.e)));
}
}
return ret;
});
Parser<catdata.Pair<Integer, catdata.Pair<List<String>, List<String>>>> p_eq = Parsers.tuple(Parsers.INDEX, Parsers.tuple(ident.sepBy(token(".")), token("="), ident.sepBy(token(".")))).map(x -> new catdata.Pair<>(x.a, new catdata.Pair<>(x.b.a, x.b.c)));
Parser<Pair<Token, List<catdata.Pair<Integer, catdata.Pair<List<String>, List<String>>>>>> p_eqs = Parsers.tuple(token("path_equations"), p_eq.many());
Parser<List<catdata.Pair<Integer, catdata.Pair<List<String>, List<String>>>>> p_eqs0 = p_eqs.map(x -> x.b);
Parser<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>> o_eq_from_p_eq = p_eq.map(x -> new catdata.Pair<>(x.first, new Quad<>("_x", null, RawTerm.fold(x.second.first, "_x"), RawTerm.fold(x.second.second, "_x"))));
Parser<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>> o_eq_old = Parsers.tuple(Parsers.INDEX, Parsers.tuple(token("forall"), ident, Parsers.tuple(token(":"), ident).optional().followedBy(token(".")), term().followedBy(token("=")), term())).map(x -> new catdata.Pair<>(x.a, new Quad<>(x.b.b, x.b.c == null ? null : x.b.c.b, x.b.d, x.b.e)));
Parser<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>> o_eq = Parsers.or(o_eq_old, o_eq_from_p_eq);
Parser<Pair<Token, List<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>>>> o_eqs = Parsers.tuple(token("observation_equations"), o_eq.many());
Parser<List<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>>> o_eqs0 = o_eqs.map(x -> x.b);
Parser<Tuple4<List<LocStr>, List<LocStr>, List<catdata.Pair<LocStr, catdata.Pair<String, String>>>, List<catdata.Pair<Integer, catdata.Pair<List<String>, List<String>>>>>> pa = Parsers.tuple(imports, entities.optional(), fks0.optional(), p_eqs0.optional());
Parser<Tuple3<List<catdata.Pair<LocStr, catdata.Pair<String, String>>>, List<catdata.Pair<Integer, Quad<String, String, RawTerm, RawTerm>>>, List<catdata.Pair<String, String>>>> pb = Parsers.tuple(atts0.optional(), o_eqs0.optional(), options);
Parser<Tuple4<Token, Token, TyExp<?, ?>, Token>> l = Parsers.tuple(token("literal"), token(":"), ty_ref.lazy(), // .map(x -> x.c);
token("{"));
// needs tyexp
Parser<SchExpRaw> ret = Parsers.tuple(l, pa, pb, token("}")).map(x -> new SchExpRaw((TyExp<Ty, Sym>) x.a.c, x.b.a, Util.newIfNull(x.b.b), Util.newIfNull(x.b.c), Util.newIfNull(x.b.d), Util.newIfNull(x.c.a), Util.newIfNull(x.c.b), x.c.c));
return ret;
}
use of catdata.Quad in project fql by CategoricalData.
the class SigOps method prod.
private static Pair<Quad<SigExp.Const, Const, Const, Fn<Triple<SigExp.Const, Const, Const>, Const>>, Quad<Map<Pair<String, String>, String>, Map<Pair<String, String>, String>, Map<Pair<String, String>, String>, Map<Pair<String, String>, String>>> prod(SigExp.Const a, SigExp.Const b) {
int node_count = 0;
Map<Pair<String, String>, String> node_map = new LinkedHashMap<>();
// fst
List<Pair<String, String>> a_objs = new LinkedList<>();
// snd
List<Pair<String, String>> b_objs = new LinkedList<>();
for (String n : a.nodes) {
for (String m : b.nodes) {
node_map.put(new Pair<>(n, m), "node" + node_count);
a_objs.add(new Pair<>("node" + node_count, n));
b_objs.add(new Pair<>("node" + node_count, m));
node_count++;
}
}
List<String> nodes = new LinkedList<>();
nodes.addAll(node_map.values());
int attr_count = 0;
Map<Pair<String, String>, String> attr_map = new LinkedHashMap<>();
// fst
List<Pair<String, String>> a_attrs = new LinkedList<>();
// snd
List<Pair<String, String>> b_attrs = new LinkedList<>();
List<Triple<String, String, String>> attrs = new LinkedList<>();
for (Triple<String, String, String> n : a.attrs) {
for (Triple<String, String, String> m : b.attrs) {
if (!n.third.equals(m.third)) {
continue;
}
String k = node_map.get(new Pair<>(n.second, m.second));
attrs.add(new Triple<>("attr" + attr_count, k, n.third));
attr_map.put(new Pair<>(n.first, m.first), "attr" + attr_count);
a_attrs.add(new Pair<>("attr" + attr_count, n.first));
b_attrs.add(new Pair<>("attr" + attr_count, m.first));
attr_count++;
}
}
int edge_count = 0;
Map<Pair<String, String>, String> edge_map_1 = new LinkedHashMap<>();
Map<Pair<String, String>, String> edge_map_2 = new LinkedHashMap<>();
// fst
List<Pair<String, List<String>>> a_edges = new LinkedList<>();
// snd
List<Pair<String, List<String>>> b_edges = new LinkedList<>();
List<Triple<String, String, String>> edges = new LinkedList<>();
for (Triple<String, String, String> n : a.arrows) {
for (String m : b.nodes) {
String k1 = node_map.get(new Pair<>(n.second, m));
String k2 = node_map.get(new Pair<>(n.third, m));
edges.add(new Triple<>("edge" + edge_count, k1, k2));
edge_map_1.put(new Pair<>(n.first, m), "edge" + edge_count);
List<String> al = new LinkedList<>();
al.add(n.second);
al.add(n.first);
a_edges.add(new Pair<>("edge" + edge_count, al));
List<String> bl = new LinkedList<>();
bl.add(m);
b_edges.add(new Pair<>("edge" + edge_count, bl));
edge_count++;
}
}
for (Triple<String, String, String> n : b.arrows) {
for (String m : a.nodes) {
String k1 = node_map.get(new Pair<>(m, n.second));
String k2 = node_map.get(new Pair<>(m, n.third));
edges.add(new Triple<>("edge" + edge_count, k1, k2));
edge_map_2.put(new Pair<>(n.first, m), "edge" + edge_count);
List<String> al = new LinkedList<>();
al.add(n.second);
al.add(n.first);
b_edges.add(new Pair<>("edge" + edge_count, al));
List<String> bl = new LinkedList<>();
bl.add(m);
a_edges.add(new Pair<>("edge" + edge_count, bl));
edge_count++;
}
}
List<Pair<List<String>, List<String>>> eqs = new LinkedList<>();
for (Triple<String, String, String> n : a.arrows) {
for (Triple<String, String, String> m : b.arrows) {
List<String> lhs = new LinkedList<>();
List<String> rhs = new LinkedList<>();
String src = node_map.get(new Pair<>(n.second, m.second));
String lhs1 = edge_map_1.get(new Pair<>(n.first, m.second));
String lhs2 = edge_map_2.get(new Pair<>(m.first, n.third));
lhs.add(src);
lhs.add(lhs1);
lhs.add(lhs2);
String rhs1 = edge_map_2.get(new Pair<>(m.first, n.second));
String rhs2 = edge_map_1.get(new Pair<>(n.first, m.third));
rhs.add(src);
rhs.add(rhs1);
rhs.add(rhs2);
eqs.add(new Pair<>(lhs, rhs));
}
}
for (Pair<List<String>, List<String>> eqA : a.eqs) {
for (String srcB : b.nodes) {
List<String> lhsA = new LinkedList<>(eqA.first);
List<String> rhsA = new LinkedList<>(eqA.second);
String srcA = lhsA.remove(0);
rhsA.remove(0);
String src = node_map.get(new Pair<>(srcA, srcB));
List<String> lhs = new LinkedList<>();
List<String> rhs = new LinkedList<>();
lhs.add(src);
rhs.add(src);
for (String k : lhsA) {
lhs.add(edge_map_1.get(new Pair<>(k, srcB)));
}
for (String k : rhsA) {
rhs.add(edge_map_1.get(new Pair<>(k, srcB)));
}
eqs.add(new Pair<>(lhs, rhs));
}
}
for (Pair<List<String>, List<String>> eqA : b.eqs) {
for (String srcB : a.nodes) {
List<String> lhsA = new LinkedList<>(eqA.first);
List<String> rhsA = new LinkedList<>(eqA.second);
String srcA = lhsA.remove(0);
rhsA.remove(0);
String src = node_map.get(new Pair<>(srcB, srcA));
List<String> lhs = new LinkedList<>();
List<String> rhs = new LinkedList<>();
lhs.add(src);
rhs.add(src);
for (String k : lhsA) {
lhs.add(edge_map_2.get(new Pair<>(k, srcB)));
}
for (String k : rhsA) {
rhs.add(edge_map_2.get(new Pair<>(k, srcB)));
}
eqs.add(new Pair<>(lhs, rhs));
}
}
SigExp.Const sig = new SigExp.Const(nodes, attrs, edges, eqs);
Const fst = new Const(a_objs, a_attrs, a_edges, sig, a);
Const snd = new Const(b_objs, b_attrs, b_edges, sig, b);
Fn<Triple<SigExp.Const, Const, Const>, Const> pair = x -> {
SigExp.Const c = x.first;
Const f = x.second;
Const g = x.third;
if (!f.src.equals(g.src)) {
throw new RuntimeException("Sources don't agree: " + f.src + " and " + g.src);
}
if (!f.dst.equals(a)) {
throw new RuntimeException("Target of " + f + " is not " + a);
}
if (!g.dst.equals(b)) {
throw new RuntimeException("Target of " + g + "is not " + b);
}
List<Pair<String, String>> objs = new LinkedList<>();
for (String obj_c : c.nodes) {
objs.add(new Pair<>(obj_c, node_map.get(new Pair<>(lookup(obj_c, f.objs), lookup(obj_c, g.objs)))));
}
List<Pair<String, String>> attrs1 = new LinkedList<>();
for (Triple<String, String, String> attr_c : c.attrs) {
attrs1.add(new Pair<>(attr_c.first, attr_map.get(new Pair<>(lookup(attr_c.first, f.attrs), lookup(attr_c.first, g.attrs)))));
}
List<Pair<String, List<String>>> arrows = new LinkedList<>();
for (Triple<String, String, String> edge_c : c.arrows) {
List<String> fc = lookup(edge_c.first, f.arrows);
List<String> gc = lookup(edge_c.first, g.arrows);
List<String> ret = new LinkedList<>();
String fcN = fc.get(0);
String gcN = gc.get(0);
String node_start = node_map.get(new Pair<>(fcN, gcN));
ret.add(node_start);
for (int i = 1; i < fc.size(); i++) {
String fcE = fc.get(i);
Pair<String, String> p = new Pair<>(fcE, gcN);
String v = edge_map_1.get(p);
ret.add(v);
}
node_start = lookup(edge_c.third, f.objs);
for (int i = 1; i < gc.size(); i++) {
String gcE = gc.get(i);
Pair<String, String> p = new Pair<>(gcE, node_start);
String v = edge_map_2.get(p);
ret.add(v);
}
arrows.add(new Pair<>(edge_c.first, ret));
}
Const ret = new Const(objs, attrs1, arrows, c, sig);
return ret;
};
return new Pair<>(new Quad<>(sig, fst, snd, pair), new Quad<>(node_map, attr_map, edge_map_1, edge_map_2));
}
use of catdata.Quad in project fql by CategoricalData.
the class Transform method doView.
// public JComponent lowerComp() throws FQLException {
// JComponent c = src.thesig.pretty();
// c.setMaximumSize(new Dimension(400,100));
// return c;
// }
/*
* public JComponent lowerComp(String s, String d) { int size =
* src.thesig.nodes.size();
*
* // JPanel pan = new JPanel(new GridLayout(1, size + 1)); // for (Node n :
* src.thesig.nodes) { // JLabel l = new JLabel(n.string); //
* l.setOpaque(true); // l.setHorizontalAlignment(SwingConstants.CENTER); //
* l.setBackground(sColor); // pan.add(l); // }
*
* //JPanel xxx = new JPanel(); // xxx.add(new JLabel(" ")); //JPanel yu =
* new MyLabel2(); // yu.setSize(20, 12); //xxx.add(new MyLabel2()); //
* xxx.add(new JLabel(s + " (source)")); // xxx.add(new JLabel(" ")); //
* JPanel uy = new MyLabel(); // uy.setSize(20,20); // xxx.add(uy); //
* xxx.add(new JLabel(d + " (target)")); // pan.add(xxx); // pan.set
* JScrollPane p = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER,
* JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
*
* pan.setBorder(BorderFactory.createTitledBorder(
* BorderFactory.createEmptyBorder(2, 2, 2, 2), "Legend"));
* p.setViewportView(pan); return p; }
*/
@SuppressWarnings("unchecked")
private static JPanel doView(Color scolor, Color tcolor, @SuppressWarnings("unused") String src_n, @SuppressWarnings("unused") String dst_n, Graph<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>> first, Map<Quad<Node, Object, String, Boolean>, Map<Attribute<Node>, Object>> second) {
// HashMap<Pair<Node, Object>,String> map = new HashMap<>();
JPanel cards = new JPanel(new CardLayout());
try {
Class<?> c = Class.forName(FqlOptions.layout_prefix + DefunctGlobalOptions.debug.fql.trans_graph);
Constructor<?> x = c.getConstructor(Graph.class);
Layout<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>> layout = (Layout<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>>) x.newInstance(first);
layout.setSize(new Dimension(600, 350));
VisualizationViewer<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>> vv = new VisualizationViewer<>(layout);
Function<Quad<Node, Object, String, Boolean>, Paint> vertexPaint = (Quad<Node, Object, String, Boolean> i) -> i.fourth ? scolor : tcolor;
DefaultModalGraphMouse<String, String> gm = new DefaultModalGraphMouse<>();
gm.setMode(Mode.TRANSFORMING);
vv.setGraphMouse(gm);
gm.setMode(Mode.PICKING);
// Set up a new stroke Transformer for the edges
float[] dash = { 1.0f };
Stroke edgeStroke = new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 10.0f);
// Function<String, Stroke> edgeStrokeTransformer = new
// Function<String, Stroke>() {
// public Stroke transform(String s) {
// return edgeStroke;
// }
// };
vv.getRenderContext().setVertexLabelRenderer(new MyVertexT(cards));
Stroke bs = new BasicStroke();
Function<Pair<Path, Integer>, Stroke> edgeStrokeTransformer = (Pair<Path, Integer> s) -> (s.first == null) ? edgeStroke : bs;
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);
// vv.getRenderContext().setVertexLabelTransformer(
// new ToStringLabeller());
vv.getRenderContext().setEdgeLabelTransformer((Pair<Path, Integer> t) -> (t.first == null) ? "" : t.first.toString());
// new ToStringLabeller());
// vv.getRenderer().getVertexRenderer().
// vv.getRenderContext().setLabelOffset(20);
// vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
vv.getRenderContext().setVertexLabelTransformer((Quad<Node, Object, String, Boolean> t) -> t.third + "." + t.first + "." + t.second);
// vv.getRenderer().setVertexRenderer(new MyRenderer());
JPanel ret = new JPanel(new BorderLayout());
JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
for (Quad<Node, Object, String, Boolean> n : first.getVertices()) {
Map<Attribute<Node>, Object> s = second.get(n);
Object[] columnNames = new Object[s.keySet().size()];
Object[][] rowData = new Object[1][s.keySet().size()];
int i = 0;
// Map<Attribute<Node>, Object> v = ma;
for (Attribute<Node> a : s.keySet()) {
columnNames[i] = a.name;
rowData[0][i] = s.get(a);
i++;
}
// }
JPanel p = new JPanel(new GridLayout(1, 1));
@SuppressWarnings("serial") JTable table = new JTable(rowData, columnNames) {
@Override
public Dimension getPreferredScrollableViewportSize() {
Dimension d = getPreferredSize();
return new Dimension(d.width, d.height);
}
};
JScrollPane jsp = new JScrollPane(table);
p.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "Attributes for " + n.second));
p.add(jsp);
cards.add(p, n.second.toString());
}
cards.add(new JPanel(), "blank");
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "blank");
pane.add(new GraphZoomScrollPane(vv));
pane.setResizeWeight(1.0d);
pane.add(cards);
cards.setPreferredSize(new Dimension(400, 100));
ret.add(pane, BorderLayout.CENTER);
// JComponent iii = lowerComp(src_n, dst_n);
// iii.setPreferredSize(new Dimension(1, 60));
// ret.add(iii, BorderLayout.NORTH);
ret.setBorder(BorderFactory.createEtchedBorder());
return ret;
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException();
}
}
use of catdata.Quad in project fql by CategoricalData.
the class Transform method build.
private Pair<Graph<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>>, HashMap<Quad<Node, Object, String, Boolean>, Map<Attribute<Node>, Object>>> build(String src_n, String dst_n) throws FQLException {
FinCat<Node, Path> c = src.thesig.toCategory2().first;
HashMap<Quad<Node, Object, String, Boolean>, Map<Attribute<Node>, Object>> map = new HashMap<>();
Graph<Quad<Node, Object, String, Boolean>, Pair<Path, Integer>> g2 = new DirectedSparseMultigraph<>();
for (Node n : c.objects) {
for (Pair<Object, Object> o : src.data.get(n.string)) {
Quad<Node, Object, String, Boolean> xx = new Quad<>(n, o.first, src_n, true);
g2.addVertex(xx);
List<Attribute<Node>> attrs = src.thesig.attrsFor(n);
Map<Attribute<Node>, Object> m = new HashMap<>();
for (Attribute<Node> attr : attrs) {
Object a = lookup(src.data.get(attr.name), o.first);
m.put(attr, a);
}
map.put(xx, m);
}
}
int j = 0;
for (Quad<Node, Object, String, Boolean> x : g2.getVertices()) {
for (Quad<Node, Object, String, Boolean> y : g2.getVertices()) {
if (!x.third.equals(y.third)) {
continue;
}
Set<Arr<Node, Path>> h = c.hom(x.first, y.first);
for (Arr<Node, Path> arr : h) {
if (c.isId(arr)) {
continue;
}
if (!DefunctGlobalOptions.debug.fql.ALL_GR_PATHS && arr.arr.path.size() != 1) {
continue;
}
if (doLookup(src, arr.arr, x.second, y.second)) {
g2.addEdge(new Pair<>(arr.arr, j++), x, y);
}
}
}
}
for (Node n : c.objects) {
for (Pair<Object, Object> o : dst.data.get(n.string)) {
Quad<Node, Object, String, Boolean> xx = new Quad<>(n, o.first, dst_n, false);
g2.addVertex(xx);
List<Attribute<Node>> attrs = dst.thesig.attrsFor(n);
Map<Attribute<Node>, Object> m = new HashMap<>();
for (Attribute<Node> attr : attrs) {
Object a = lookup(dst.data.get(attr.name), o.first);
m.put(attr, a);
}
map.put(xx, m);
}
}
for (Quad<Node, Object, String, Boolean> x : g2.getVertices()) {
for (Quad<Node, Object, String, Boolean> y : g2.getVertices()) {
Set<Arr<Node, Path>> h = c.hom(x.first, y.first);
for (Arr<Node, Path> arr : h) {
if (c.isId(arr)) {
continue;
}
if (!DefunctGlobalOptions.debug.fql.ALL_GR_PATHS && arr.arr.path.size() != 1) {
continue;
}
if (doLookup(dst, arr.arr, x.second, y.second)) {
g2.addEdge(new Pair<>(arr.arr, j++), x, y);
}
}
}
}
for (String k : data.keySet()) {
Set<Pair<Object, Object>> v = data.get(k);
for (Pair<Object, Object> i : v) {
Node n = src.thesig.getNode(k);
g2.addEdge(new Pair<>(null, j++), new Quad<>(n, i.first, src_n, true), new Quad<>(n, i.second, dst_n, false));
}
}
return new Pair<>(g2, map);
}
Aggregations