diff options
author | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-30 18:03:48 +0200 |
---|---|---|
committer | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-30 18:03:48 +0200 |
commit | e11bce7ad3e803e80883499fec0ad6e4540ffe43 (patch) | |
tree | ca3ad9d5b9137e9455485e43350a4a353f487f22 /Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding | |
parent | Disable unrepairable match scoping for now (diff) | |
download | VIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.tar.gz VIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.tar.zst VIATRA-Generator-e11bce7ad3e803e80883499fec0ad6e4540ffe43.zip |
Add modified VIATRA-DSE version
Diffstat (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding')
13 files changed, 900 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java new file mode 100644 index 00000000..afcba7b6 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProvider.java | |||
@@ -0,0 +1,45 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | import org.eclipse.emf.common.notify.Notifier; | ||
14 | import org.eclipse.emf.ecore.EClass; | ||
15 | import org.eclipse.emf.ecore.EObject; | ||
16 | |||
17 | /** | ||
18 | * Implementation of this interface is responsible to provide {@link EObject}s of a given {@link EClass} for | ||
19 | * {@link TheStateCoder} | ||
20 | * | ||
21 | * @author Andras Szabolcs Nagy | ||
22 | * | ||
23 | */ | ||
24 | public interface IObjectsProvider { | ||
25 | |||
26 | /** | ||
27 | * Initialize the {@link IObjectsProvider} on a given model and {@link StatecodingDependencyGraph}. | ||
28 | * | ||
29 | * @param notifier | ||
30 | * The root of the model. | ||
31 | * @param statecodingDependencyGraph | ||
32 | * The state coding dependency graph. | ||
33 | */ | ||
34 | void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph); | ||
35 | |||
36 | /** | ||
37 | * Returns the instances of an {@link EClass} in a model. | ||
38 | * | ||
39 | * @param eClass | ||
40 | * The class of the objects. | ||
41 | * @return The collection of the instances. | ||
42 | */ | ||
43 | Collection<EObject> getEObjects(EClass eClass); | ||
44 | |||
45 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java new file mode 100644 index 00000000..931eb1a2 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IObjectsProviderFactory.java | |||
@@ -0,0 +1,25 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | /** | ||
12 | * Interface for creating {@link IObjectsProvider} instances. | ||
13 | * | ||
14 | * @author Andras Szabolcs Nagy | ||
15 | */ | ||
16 | public interface IObjectsProviderFactory { | ||
17 | |||
18 | /** | ||
19 | * Creates an {@link IObjectsProvider} implementation. | ||
20 | * | ||
21 | * @return The newly created {@link IObjectsProvider}. | ||
22 | */ | ||
23 | IObjectsProvider createObjectsProvider(); | ||
24 | |||
25 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java new file mode 100644 index 00000000..e38d45d3 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProvider.java | |||
@@ -0,0 +1,60 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | import java.util.HashSet; | ||
13 | import java.util.Set; | ||
14 | |||
15 | import org.apache.log4j.Logger; | ||
16 | import org.eclipse.emf.common.notify.Notifier; | ||
17 | import org.eclipse.emf.ecore.EClass; | ||
18 | import org.eclipse.emf.ecore.EObject; | ||
19 | import org.eclipse.viatra.dse.api.DSEException; | ||
20 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
21 | import org.eclipse.viatra.query.runtime.base.api.IndexingLevel; | ||
22 | import org.eclipse.viatra.query.runtime.base.api.NavigationHelper; | ||
23 | import org.eclipse.viatra.query.runtime.emf.EMFScope; | ||
24 | import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; | ||
25 | |||
26 | public class IncrementalObjectProvider implements IObjectsProvider { | ||
27 | |||
28 | private Logger logger = Logger.getLogger(getClass()); | ||
29 | private NavigationHelper baseIndex; | ||
30 | |||
31 | @Override | ||
32 | public void init(Notifier notifier, StatecodingDependencyGraph statecodingDependencyGraph) { | ||
33 | |||
34 | try { | ||
35 | EMFScope scope = new EMFScope(notifier); | ||
36 | ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope); | ||
37 | |||
38 | Set<EClass> classes = new HashSet<EClass>(); | ||
39 | // Set<EReference> references = new HashSet<EReference>(); | ||
40 | for (StatecodingNode node : statecodingDependencyGraph.getNodes()) { | ||
41 | classes.add(node.getClazz()); | ||
42 | // for (StatecodingDependency dependency : node.getStatecodingDependencies()) { | ||
43 | // // TODO inverse reference | ||
44 | // references.add(dependency.eReference); | ||
45 | // } | ||
46 | } | ||
47 | baseIndex = EMFScope.extractUnderlyingEMFIndex(queryEngine); | ||
48 | baseIndex.registerEClasses(classes, IndexingLevel.FULL); | ||
49 | } catch (ViatraQueryException e) { | ||
50 | logger.error("Failed to initialize VIATRA Query engine on the given notifier", e); | ||
51 | throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier"); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | @Override | ||
56 | public Collection<EObject> getEObjects(EClass eClass) { | ||
57 | return baseIndex.getAllInstances(eClass); | ||
58 | } | ||
59 | |||
60 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java new file mode 100644 index 00000000..97011436 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/IncrementalObjectProviderFactory.java | |||
@@ -0,0 +1,18 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | public class IncrementalObjectProviderFactory implements IObjectsProviderFactory { | ||
12 | |||
13 | @Override | ||
14 | public IncrementalObjectProvider createObjectsProvider() { | ||
15 | return new IncrementalObjectProvider(); | ||
16 | } | ||
17 | |||
18 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java new file mode 100644 index 00000000..67b1982d --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependency.java | |||
@@ -0,0 +1,33 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import org.eclipse.emf.ecore.EReference; | ||
12 | |||
13 | public class StatecodingDependency { | ||
14 | |||
15 | protected EReference eReference; | ||
16 | protected StatecodingNode node; | ||
17 | protected boolean isContained; | ||
18 | protected StatecodingDependencyType type; | ||
19 | |||
20 | public StatecodingDependency(EReference eReference, StatecodingNode node, boolean isContained, | ||
21 | StatecodingDependencyType type) { | ||
22 | super(); | ||
23 | this.eReference = eReference; | ||
24 | this.node = node; | ||
25 | this.isContained = isContained; | ||
26 | this.type = type; | ||
27 | } | ||
28 | |||
29 | public StatecodingDependency(EReference eReference, StatecodingNode node) { | ||
30 | this(eReference, node, false, StatecodingDependencyType.NORMAL); | ||
31 | } | ||
32 | |||
33 | } \ No newline at end of file | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java new file mode 100644 index 00000000..6f7255a3 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyGraph.java | |||
@@ -0,0 +1,44 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import java.util.ArrayList; | ||
12 | import java.util.List; | ||
13 | |||
14 | import org.eclipse.emf.ecore.EClass; | ||
15 | |||
16 | public class StatecodingDependencyGraph { | ||
17 | |||
18 | private List<StatecodingNode> nodes = new ArrayList<StatecodingNode>(); | ||
19 | |||
20 | public StatecodingNode createNode(EClass clazz) { | ||
21 | StatecodingNode node = new StatecodingNode(clazz); | ||
22 | node.setGraph(this); | ||
23 | addNode(node); | ||
24 | return node; | ||
25 | } | ||
26 | |||
27 | public void addNode(StatecodingNode node) { | ||
28 | nodes.add(node); | ||
29 | } | ||
30 | |||
31 | public StatecodingNode getNodeByClass(EClass eClass) { | ||
32 | for (StatecodingNode node : nodes) { | ||
33 | if (node.getClazz().equals(eClass)) { | ||
34 | return node; | ||
35 | } | ||
36 | } | ||
37 | return null; | ||
38 | } | ||
39 | |||
40 | public List<StatecodingNode> getNodes() { | ||
41 | return nodes; | ||
42 | } | ||
43 | |||
44 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java new file mode 100644 index 00000000..bdd4677d --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingDependencyType.java | |||
@@ -0,0 +1,15 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | public enum StatecodingDependencyType { | ||
12 | |||
13 | NORMAL, | ||
14 | INVERSE | ||
15 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java new file mode 100644 index 00000000..91fc28cf --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNode.java | |||
@@ -0,0 +1,100 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import java.util.ArrayList; | ||
12 | import java.util.Comparator; | ||
13 | import java.util.List; | ||
14 | import java.util.Set; | ||
15 | import java.util.TreeSet; | ||
16 | |||
17 | import org.eclipse.emf.ecore.EAttribute; | ||
18 | import org.eclipse.emf.ecore.EClass; | ||
19 | import org.eclipse.emf.ecore.EReference; | ||
20 | |||
21 | public class StatecodingNode { | ||
22 | |||
23 | private StatecodingDependencyGraph graph; | ||
24 | |||
25 | private final EClass clazz; | ||
26 | private Set<EAttribute> attributes = new TreeSet<EAttribute>(Comparator.comparing(EAttribute::getName)); | ||
27 | private List<StatecodingDependency> dependencies = new ArrayList<StatecodingDependency>(); | ||
28 | private boolean stateCodeIsId = false; | ||
29 | private StatecodingNodeType statecodingNodeType = StatecodingNodeType.CREATE_AND_DELETE; | ||
30 | |||
31 | public StatecodingNode(EClass clazz) { | ||
32 | this.clazz = clazz; | ||
33 | } | ||
34 | |||
35 | public StatecodingNode withAttribute(EAttribute attribute) { | ||
36 | attributes.add(attribute); | ||
37 | return this; | ||
38 | } | ||
39 | |||
40 | public StatecodingNode withType(StatecodingNodeType type) { | ||
41 | statecodingNodeType = type; | ||
42 | return this; | ||
43 | } | ||
44 | |||
45 | public StatecodingNode withUniqueness() { | ||
46 | stateCodeIsId = true; | ||
47 | return this; | ||
48 | } | ||
49 | |||
50 | public StatecodingNode withDependency(EReference reference, StatecodingNode node) { | ||
51 | dependencies.add(new StatecodingDependency(reference, node)); | ||
52 | return this; | ||
53 | } | ||
54 | |||
55 | public StatecodingNode withInverseDependency(EReference reference, StatecodingNode node) { | ||
56 | dependencies.add(new StatecodingDependency(reference, node, false, StatecodingDependencyType.INVERSE)); | ||
57 | return this; | ||
58 | } | ||
59 | |||
60 | public void addDependency(StatecodingDependency statecodingDependency) { | ||
61 | dependencies.add(statecodingDependency); | ||
62 | } | ||
63 | |||
64 | public EClass getClazz() { | ||
65 | return clazz; | ||
66 | } | ||
67 | |||
68 | public boolean isStateCodeIsId() { | ||
69 | return stateCodeIsId; | ||
70 | } | ||
71 | |||
72 | public void setStateCodeIsId(boolean stateCodeIsId) { | ||
73 | this.stateCodeIsId = stateCodeIsId; | ||
74 | } | ||
75 | |||
76 | public StatecodingNodeType getStatecodingNodeType() { | ||
77 | return statecodingNodeType; | ||
78 | } | ||
79 | |||
80 | public void setStatecodingNodeType(StatecodingNodeType statecodingNodeType) { | ||
81 | this.statecodingNodeType = statecodingNodeType; | ||
82 | } | ||
83 | |||
84 | public Set<EAttribute> getAttributes() { | ||
85 | return attributes; | ||
86 | } | ||
87 | |||
88 | public List<StatecodingDependency> getStatecodingDependencies() { | ||
89 | return dependencies; | ||
90 | } | ||
91 | |||
92 | public StatecodingDependencyGraph getGraph() { | ||
93 | return graph; | ||
94 | } | ||
95 | |||
96 | public void setGraph(StatecodingDependencyGraph graph) { | ||
97 | this.graph = graph; | ||
98 | } | ||
99 | |||
100 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java new file mode 100644 index 00000000..c902a7a6 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/StatecodingNodeType.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | public enum StatecodingNodeType { | ||
12 | |||
13 | FIXED, | ||
14 | ONLY_CREATE, | ||
15 | ONLY_DELETE, | ||
16 | CREATE_AND_DELETE | ||
17 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java new file mode 100644 index 00000000..4601ff08 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoder.java | |||
@@ -0,0 +1,215 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import java.util.Arrays; | ||
12 | import java.util.Collection; | ||
13 | import java.util.List; | ||
14 | import java.util.Set; | ||
15 | |||
16 | import org.eclipse.emf.common.notify.Notifier; | ||
17 | import org.eclipse.emf.common.util.EList; | ||
18 | import org.eclipse.emf.ecore.EAttribute; | ||
19 | import org.eclipse.emf.ecore.EObject; | ||
20 | import org.eclipse.viatra.dse.api.DSEException; | ||
21 | import org.eclipse.viatra.dse.statecode.IStateCoder; | ||
22 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
23 | |||
24 | public class TheStateCoder implements IStateCoder { | ||
25 | |||
26 | private StatecodingDependencyGraph sdg; | ||
27 | private IObjectsProvider objectProvider; | ||
28 | |||
29 | public TheStateCoder(StatecodingDependencyGraph sdg, IObjectsProvider objectProvider) { | ||
30 | this.sdg = sdg; | ||
31 | this.objectProvider = objectProvider; | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public void init(Notifier notifier) { | ||
36 | // TODO checks | ||
37 | // TODO node sorting based on traversal - in factory | ||
38 | |||
39 | // this.notifier = notifier; | ||
40 | // try { | ||
41 | // EMFScope scope = new EMFScope(notifier); | ||
42 | // queryEngine = ViatraQueryEngine.on(scope); | ||
43 | // } catch (ViatraQueryException e1) { | ||
44 | // logger.error("Failed to initialize VIATRA Query engine on the given notifier", e1); | ||
45 | // throw new DSEException("Failed to initialize VIATRA Query engine on the given notifier"); | ||
46 | // } | ||
47 | |||
48 | objectProvider.init(notifier, sdg); | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public String createStateCode() { | ||
53 | |||
54 | StringBuilder sb = new StringBuilder(); | ||
55 | |||
56 | // TODO sort | ||
57 | for (StatecodingNode node : sdg.getNodes()) { | ||
58 | sb.append(node.getClazz().getName()); | ||
59 | sb.append(':'); | ||
60 | sb.append(addStateCode(node)); | ||
61 | sb.append('|'); | ||
62 | } | ||
63 | sb.deleteCharAt(sb.length() - 1); | ||
64 | |||
65 | return sb.toString(); | ||
66 | |||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public Object createActivationCode(IPatternMatch match) { | ||
71 | // TODO root object | ||
72 | // TODO parameterless? | ||
73 | |||
74 | int i = 0; | ||
75 | StringBuilder sb = new StringBuilder(); | ||
76 | Object object; | ||
77 | do { | ||
78 | object = match.get(i++); | ||
79 | if (object != null) { | ||
80 | if (object instanceof EObject) { | ||
81 | EObject eObject = (EObject) object; | ||
82 | sb.append(addStateCode(sdg.getNodeByClass(eObject.eClass()), eObject)); | ||
83 | } else { | ||
84 | // TODO toString or not to toString | ||
85 | } | ||
86 | } | ||
87 | } while (object != null); | ||
88 | |||
89 | return sb.toString(); | ||
90 | } | ||
91 | |||
92 | public String addStateCode(StatecodingNode node, EObject eObject) { | ||
93 | StringBuilder sb = new StringBuilder(); | ||
94 | |||
95 | Set<EAttribute> attributes = node.getAttributes(); | ||
96 | if (!attributes.isEmpty()) { | ||
97 | for (EAttribute eAttribute : attributes) { | ||
98 | // attributes are sorted | ||
99 | // TODO handle collection | ||
100 | sb.append(eObject.eGet(eAttribute)); | ||
101 | sb.append(';'); | ||
102 | } | ||
103 | sb.deleteCharAt(sb.length() - 1); | ||
104 | } | ||
105 | |||
106 | List<StatecodingDependency> dependencies = node.getStatecodingDependencies(); | ||
107 | int dependenciesSize = dependencies.size(); | ||
108 | if (dependenciesSize > 0) { | ||
109 | String[] codeParts = new String[dependenciesSize]; | ||
110 | int i = 0; | ||
111 | for (StatecodingDependency dependency : dependencies) { | ||
112 | String code = addStateCodeFromDependency(dependency, eObject); | ||
113 | codeParts[i++] = code; | ||
114 | } | ||
115 | Arrays.sort(codeParts); | ||
116 | |||
117 | sb.append("("); | ||
118 | sb.append(codeParts[0]); | ||
119 | for (i = 1; i < codeParts.length; i++) { | ||
120 | sb.append(';'); | ||
121 | sb.append(codeParts[i]); | ||
122 | } | ||
123 | sb.append(")"); | ||
124 | } | ||
125 | return sb.toString(); | ||
126 | } | ||
127 | |||
128 | public String addStateCode(StatecodingNode node) { | ||
129 | Collection<EObject> eObjects = objectProvider.getEObjects(node.getClazz()); | ||
130 | int size = eObjects.size(); | ||
131 | |||
132 | if (size > 0) { | ||
133 | String[] codeParts = new String[size]; | ||
134 | int i = 0; | ||
135 | for (EObject eObject : eObjects) { | ||
136 | String code = addStateCode(node, eObject); | ||
137 | codeParts[i++] = code; | ||
138 | } | ||
139 | Arrays.sort(codeParts); | ||
140 | |||
141 | StringBuilder sb = new StringBuilder(); | ||
142 | sb.append(codeParts[0]); | ||
143 | for (i = 1; i < codeParts.length; i++) { | ||
144 | sb.append(';'); | ||
145 | sb.append(codeParts[i]); | ||
146 | } | ||
147 | return sb.toString(); | ||
148 | } | ||
149 | |||
150 | return ""; | ||
151 | } | ||
152 | |||
153 | public String addStateCodeFromDependency(StatecodingDependency sd, EObject eObject) { | ||
154 | |||
155 | if (sd.type.equals(StatecodingDependencyType.NORMAL)) { | ||
156 | |||
157 | Object eReferred = eObject.eGet(sd.eReference); | ||
158 | if (eReferred == null) { | ||
159 | return ""; | ||
160 | } else if (eReferred instanceof EList<?>) { | ||
161 | EList<?> refferedList = (EList<?>) eReferred; | ||
162 | // TODO test | ||
163 | if (!refferedList.isEmpty()) { | ||
164 | |||
165 | String[] codeParts = new String[refferedList.size()]; | ||
166 | int i = 0; | ||
167 | for (Object referredEObject : refferedList) { | ||
168 | String code = addStateCode(sd.node, (EObject) referredEObject); | ||
169 | codeParts[i++] = code; | ||
170 | } | ||
171 | Arrays.sort(codeParts); | ||
172 | |||
173 | StringBuilder sb = new StringBuilder(); | ||
174 | sb.append('['); | ||
175 | sb.append(codeParts[0]); | ||
176 | for (i = 1; i < codeParts.length; i++) { | ||
177 | sb.append(';'); | ||
178 | sb.append(codeParts[i]); | ||
179 | } | ||
180 | sb.append(']'); | ||
181 | return sb.toString(); | ||
182 | |||
183 | } | ||
184 | } else if (eReferred instanceof EObject) { | ||
185 | return addStateCode(sd.node, (EObject) eReferred); | ||
186 | } else { | ||
187 | throw new DSEException("The EObject " + eObject.toString() + " does not have a feature " | ||
188 | + eReferred.toString() + "."); | ||
189 | } | ||
190 | |||
191 | } else { | ||
192 | for (EObject dependentEObject : objectProvider.getEObjects(sd.node.getClazz())) { | ||
193 | Object eReferred = dependentEObject.eGet(sd.eReference); | ||
194 | if (eReferred == null) { | ||
195 | continue; | ||
196 | } else if (eReferred instanceof EList<?>) { | ||
197 | // TODO this is slow, use VIATRA Query | ||
198 | for (Object referredEObject : ((EList<?>) eReferred)) { | ||
199 | if (referredEObject.equals(eObject)) { | ||
200 | return addStateCode(sd.node, (EObject) dependentEObject); | ||
201 | } | ||
202 | } | ||
203 | } else if (eReferred.equals(eObject)) { | ||
204 | // Probably never happens? | ||
205 | return addStateCode(sd.node, (EObject) dependentEObject); | ||
206 | } else { | ||
207 | throw new DSEException("The EObject " + eObject.toString() + " does not have a feature " | ||
208 | + eReferred.toString() + "."); | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return ""; | ||
214 | } | ||
215 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java new file mode 100644 index 00000000..eeb6e48f --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/TheStateCoderFactory.java | |||
@@ -0,0 +1,40 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding; | ||
10 | |||
11 | import org.eclipse.viatra.dse.statecode.IStateCoder; | ||
12 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory; | ||
13 | |||
14 | public class TheStateCoderFactory implements IStateCoderFactory { | ||
15 | |||
16 | private StatecodingDependencyGraph sdg; | ||
17 | private IObjectsProviderFactory objectProviderFactory; | ||
18 | |||
19 | public TheStateCoderFactory(StatecodingDependencyGraph sdg) { | ||
20 | this(sdg, new IncrementalObjectProviderFactory()); | ||
21 | } | ||
22 | |||
23 | public TheStateCoderFactory(StatecodingDependencyGraph sdg, IObjectsProviderFactory objectProviderFactory) { | ||
24 | this.sdg = sdg; | ||
25 | this.objectProviderFactory = objectProviderFactory; | ||
26 | |||
27 | // TODO cyclic dependency? - exception | ||
28 | |||
29 | // TODO make plan for traversal | ||
30 | |||
31 | // TODO If the type is FIXED and all dependency is FIXED then do not create state code for it (them) | ||
32 | // This is not true :( e.g. matchmaking - they are fixed, but the references must be encoded | ||
33 | } | ||
34 | |||
35 | @Override | ||
36 | public IStateCoder createStateCoder() { | ||
37 | return new TheStateCoder(sdg, objectProviderFactory.createObjectsProvider()); | ||
38 | } | ||
39 | |||
40 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java new file mode 100644 index 00000000..0f0759ae --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoder.java | |||
@@ -0,0 +1,250 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding.simple; | ||
10 | |||
11 | import java.util.Arrays; | ||
12 | import java.util.Collection; | ||
13 | import java.util.HashMap; | ||
14 | import java.util.HashSet; | ||
15 | import java.util.List; | ||
16 | import java.util.Map; | ||
17 | import java.util.Set; | ||
18 | |||
19 | import org.eclipse.emf.common.notify.Notifier; | ||
20 | import org.eclipse.emf.ecore.EAttribute; | ||
21 | import org.eclipse.emf.ecore.EClass; | ||
22 | import org.eclipse.emf.ecore.EObject; | ||
23 | import org.eclipse.emf.ecore.EReference; | ||
24 | import org.eclipse.emf.ecore.EStructuralFeature; | ||
25 | import org.eclipse.emf.ecore.EStructuralFeature.Setting; | ||
26 | import org.eclipse.viatra.dse.api.DSEException; | ||
27 | import org.eclipse.viatra.dse.statecode.IStateCoder; | ||
28 | import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements; | ||
29 | import org.eclipse.viatra.dse.util.ValueComparableEObjectStringMap; | ||
30 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
31 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
32 | import org.eclipse.viatra.query.runtime.base.api.FeatureListener; | ||
33 | import org.eclipse.viatra.query.runtime.base.api.IndexingLevel; | ||
34 | import org.eclipse.viatra.query.runtime.base.api.InstanceListener; | ||
35 | import org.eclipse.viatra.query.runtime.base.api.NavigationHelper; | ||
36 | import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper; | ||
37 | import org.eclipse.viatra.query.runtime.emf.EMFScope; | ||
38 | import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; | ||
39 | |||
40 | /** | ||
41 | * | ||
42 | * @author Andras Szabolcs Nagy | ||
43 | * | ||
44 | */ | ||
45 | public class SimpleStateCoder implements IStateCoder { | ||
46 | |||
47 | private Set<EClass> classes; | ||
48 | private Set<EStructuralFeature> features; | ||
49 | private NavigationHelper navigationHelper; | ||
50 | |||
51 | private Map<EClass, Map<EObject, String>> objectCodes; | ||
52 | private int maxDepth; | ||
53 | |||
54 | private Set<EObject> changedOrNewEObjects = new HashSet<EObject>(); | ||
55 | private Set<EObject> deletedClasses = new HashSet<EObject>(); | ||
56 | |||
57 | public SimpleStateCoder(MetaModelElements metaModelElements) { | ||
58 | this.maxDepth = 1; | ||
59 | |||
60 | classes = metaModelElements.classes; | ||
61 | features = new HashSet<EStructuralFeature>(metaModelElements.attributes); | ||
62 | features.addAll(metaModelElements.references); | ||
63 | } | ||
64 | |||
65 | @Override | ||
66 | public void init(Notifier notifier) { | ||
67 | try { | ||
68 | EMFScope scope = new EMFScope(notifier); | ||
69 | ViatraQueryEngine queryEngine = ViatraQueryEngine.on(scope); | ||
70 | EMFBaseIndexWrapper baseIndex = (EMFBaseIndexWrapper) queryEngine.getBaseIndex(); | ||
71 | navigationHelper = baseIndex.getNavigationHelper(); | ||
72 | navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL); | ||
73 | } catch (ViatraQueryException e) { | ||
74 | throw new DSEException(e); | ||
75 | } | ||
76 | |||
77 | objectCodes = new HashMap<EClass, Map<EObject, String>>(); | ||
78 | for (EClass eClass : classes) { | ||
79 | Map<EObject, String> codes = new ValueComparableEObjectStringMap(); | ||
80 | |||
81 | objectCodes.put(eClass, codes); | ||
82 | |||
83 | for (EObject eObject : navigationHelper.getDirectInstances(eClass)) { | ||
84 | codes.put(eObject, createObjectCodeWithDepth(eObject, maxDepth)); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | navigationHelper.addFeatureListener(features, new FeatureListener() { | ||
89 | |||
90 | @Override | ||
91 | public void featureInserted(EObject host, EStructuralFeature feature, Object value) { | ||
92 | changedOrNewEObjects.add(host); | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { | ||
97 | changedOrNewEObjects.add(host); | ||
98 | if (value instanceof EObject) { | ||
99 | changedOrNewEObjects.add((EObject) value); | ||
100 | } | ||
101 | } | ||
102 | }); | ||
103 | |||
104 | navigationHelper.addInstanceListener(classes, new InstanceListener() { | ||
105 | |||
106 | @Override | ||
107 | public void instanceInserted(EClass clazz, EObject instance) { | ||
108 | changedOrNewEObjects.add(instance); | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public void instanceDeleted(EClass clazz, EObject instance) { | ||
113 | deletedClasses.add(instance); | ||
114 | } | ||
115 | }); | ||
116 | } | ||
117 | |||
118 | private String createObjectCodeWithDepth(EObject eObject, int depth) { | ||
119 | |||
120 | StringBuilder sb = new StringBuilder(); | ||
121 | |||
122 | Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes(); | ||
123 | for (EAttribute eAttribute : attributes) { | ||
124 | Object value = eObject.eGet(eAttribute); | ||
125 | sb.append(value); | ||
126 | sb.append(','); | ||
127 | } | ||
128 | if (!attributes.isEmpty()) { | ||
129 | sb.deleteCharAt(sb.length() - 1); | ||
130 | } | ||
131 | if (depth > 0) { | ||
132 | sb.append('-'); | ||
133 | Collection<EReference> eReferences = eObject.eClass().getEAllReferences(); | ||
134 | for (EReference eReference : eReferences) { | ||
135 | Object value = eObject.eGet(eReference); | ||
136 | if (value == null) { | ||
137 | sb.append("null,"); | ||
138 | } else if (value instanceof EObject) { | ||
139 | sb.append(createObjectCodeWithDepth((EObject) value, depth - 1)); | ||
140 | sb.append(','); | ||
141 | } else { | ||
142 | List<EObject> referencedEObjects = (List<EObject>) value; | ||
143 | if (!referencedEObjects.isEmpty()) { | ||
144 | |||
145 | String[] codes = new String[referencedEObjects.size()]; | ||
146 | int index = 0; | ||
147 | for (EObject referencedEObject : referencedEObjects) { | ||
148 | codes[index++] = createObjectCodeWithDepth(referencedEObject, depth - 1); | ||
149 | } | ||
150 | Arrays.sort(codes); | ||
151 | sb.append('('); | ||
152 | for (String code : codes) { | ||
153 | sb.append(code); | ||
154 | } | ||
155 | sb.append("),"); | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | sb.deleteCharAt(sb.length() - 1); | ||
160 | } | ||
161 | return sb.toString(); | ||
162 | } | ||
163 | |||
164 | @Override | ||
165 | public Object createStateCode() { | ||
166 | |||
167 | refreshObjectCodes(); | ||
168 | |||
169 | StringBuilder sb = new StringBuilder(); | ||
170 | |||
171 | for (EClass eClass : classes) { | ||
172 | |||
173 | Set<EObject> instances = navigationHelper.getDirectInstances(eClass); | ||
174 | |||
175 | if (!instances.isEmpty()) { | ||
176 | |||
177 | sb.append(eClass.getName()); | ||
178 | sb.append(':'); | ||
179 | |||
180 | String[] codesToSort = new String[instances.size()]; | ||
181 | int index = 0; | ||
182 | Map<EObject, String> codes = objectCodes.get(eClass); | ||
183 | for (EObject eObject : instances) { | ||
184 | codesToSort[index++] = codes.get(eObject); | ||
185 | } | ||
186 | Arrays.sort(codesToSort); | ||
187 | for (String string : codesToSort) { | ||
188 | sb.append(string); | ||
189 | sb.append(';'); | ||
190 | } | ||
191 | sb.deleteCharAt(sb.length() - 1); | ||
192 | sb.append('|'); | ||
193 | } | ||
194 | } | ||
195 | if (sb.length() != 0) { | ||
196 | sb.deleteCharAt(sb.length() - 1); | ||
197 | } | ||
198 | return sb.toString(); | ||
199 | } | ||
200 | |||
201 | private void refreshObjectCodes() { | ||
202 | for (EObject eObject : deletedClasses) { | ||
203 | EClass eClass = eObject.eClass(); | ||
204 | objectCodes.get(eClass).remove(eObject); | ||
205 | } | ||
206 | deletedClasses.clear(); | ||
207 | |||
208 | Set<EObject> objectsToRecode = new HashSet<EObject>(); | ||
209 | for (EObject eObject : changedOrNewEObjects) { | ||
210 | objectsToRecode.add(eObject); | ||
211 | for (Setting setting : navigationHelper.getInverseReferences(eObject)) { | ||
212 | objectsToRecode.add(setting.getEObject()); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | for (EObject eObject : objectsToRecode) { | ||
217 | EClass eClass = eObject.eClass(); | ||
218 | objectCodes.get(eClass).put(eObject, createObjectCodeWithDepth(eObject, maxDepth)); | ||
219 | } | ||
220 | changedOrNewEObjects.clear(); | ||
221 | } | ||
222 | |||
223 | @Override | ||
224 | public Object createActivationCode(IPatternMatch match) { | ||
225 | |||
226 | StringBuilder sb = new StringBuilder(); | ||
227 | String[] tokens = match.specification().getFullyQualifiedName().split("\\."); | ||
228 | sb.append(tokens[tokens.length - 1]); | ||
229 | sb.append(':'); | ||
230 | Object param; | ||
231 | for (int i = 0; (param = match.get(i)) != null; i++) { | ||
232 | EObject eObject = (EObject) param; | ||
233 | |||
234 | Collection<EAttribute> attributes = eObject.eClass().getEAllAttributes(); | ||
235 | for (EAttribute eAttribute : attributes) { | ||
236 | Object value = eObject.eGet(eAttribute); | ||
237 | sb.append(value); | ||
238 | sb.append(','); | ||
239 | } | ||
240 | if (!attributes.isEmpty()) { | ||
241 | sb.deleteCharAt(sb.length() - 1); | ||
242 | } | ||
243 | |||
244 | sb.append('|'); | ||
245 | } | ||
246 | sb.deleteCharAt(sb.length() - 1); | ||
247 | return sb.toString().intern(); | ||
248 | } | ||
249 | |||
250 | } | ||
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java new file mode 100644 index 00000000..d776e8a8 --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/statecoding/simple/SimpleStateCoderFactory.java | |||
@@ -0,0 +1,38 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2015, Andras Szabolcs Nagy and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.statecoding.simple; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | import java.util.HashSet; | ||
13 | |||
14 | import org.eclipse.emf.ecore.EPackage; | ||
15 | import org.eclipse.viatra.dse.statecode.IStateCoder; | ||
16 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory; | ||
17 | import org.eclipse.viatra.dse.util.EMFHelper; | ||
18 | import org.eclipse.viatra.dse.util.EMFHelper.MetaModelElements; | ||
19 | |||
20 | /** | ||
21 | * | ||
22 | * @author Andras Szabolcs Nagy | ||
23 | * | ||
24 | */ | ||
25 | public class SimpleStateCoderFactory implements IStateCoderFactory { | ||
26 | |||
27 | private MetaModelElements metaModelElements; | ||
28 | |||
29 | public SimpleStateCoderFactory(Collection<EPackage> metaModelPackages) { | ||
30 | metaModelElements = EMFHelper.getAllMetaModelElements(new HashSet<EPackage>(metaModelPackages)); | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public IStateCoder createStateCoder() { | ||
35 | return new SimpleStateCoder(metaModelElements); | ||
36 | } | ||
37 | |||
38 | } | ||