aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/TypeJudgement.java
blob: 4447b2258c9d57a2f79f9d80151054008b108082 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*******************************************************************************
 * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-v20.html.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package tools.refinery.viatra.runtime.matchers.psystem;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Set;

import tools.refinery.viatra.runtime.matchers.context.IInputKey;
import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext;
import tools.refinery.viatra.runtime.matchers.context.InputKeyImplication;
import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint;
import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
import tools.refinery.viatra.runtime.matchers.tuple.Tuples;

/**
 * A judgement that means that the given tuple of variables will represent a tuple of values that is a member of the extensional relation identified by the given input key.
 * @author Bergmann Gabor
 *
 */
public class TypeJudgement {
    
    private IInputKey inputKey;
    private Tuple variablesTuple;
    /**
     * @param inputKey
     * @param variablesTuple
     */
    public TypeJudgement(IInputKey inputKey, Tuple variablesTuple) {
        super();
        this.inputKey = inputKey;
        this.variablesTuple = variablesTuple;
    }
    public IInputKey getInputKey() {
        return inputKey;
    }
    public Tuple getVariablesTuple() {
        return variablesTuple;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((inputKey == null) ? 0 : inputKey.hashCode());
        result = prime * result
                + ((variablesTuple == null) ? 0 : variablesTuple.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof TypeJudgement))
            return false;
        TypeJudgement other = (TypeJudgement) obj;
        if (inputKey == null) {
            if (other.inputKey != null)
                return false;
        } else if (!inputKey.equals(other.inputKey))
            return false;
        if (variablesTuple == null) {
            if (other.variablesTuple != null)
                return false;
        } else if (!variablesTuple.equals(other.variablesTuple))
            return false;
        return true;
    }
    
    public Set<TypeJudgement> getDirectlyImpliedJudgements(IQueryMetaContext context) {
        Set<TypeJudgement> results = new HashSet<TypeJudgement>();
        results.add(this);
        
        Collection<InputKeyImplication> implications = context.getImplications(this.inputKey);
        for (InputKeyImplication inputKeyImplication : implications) {
            results.add(
                transcribeImplication(inputKeyImplication)
            );
        }
        
        return results;
    }
    
    /**
     * @since 1.6
     */
    public Set<TypeJudgement> getWeakenedAlternativeJudgements(IQueryMetaContext context) {
        Set<TypeJudgement> results = new HashSet<TypeJudgement>();
        
        Collection<InputKeyImplication> implications = context.getWeakenedAlternatives(this.inputKey);
        for (InputKeyImplication inputKeyImplication : implications) {
            results.add(
                transcribeImplication(inputKeyImplication)
            );
        }
        
        return results;
    }
    
    /**
     * @since 2.0
     */
    public Map<TypeJudgement, Set<TypeJudgement>> getConditionalImpliedJudgements(IQueryMetaContext context) {
        return context.getConditionalImplications(this.inputKey).entrySet().stream().collect(Collectors.toMap(
                entry -> transcribeImplication(entry.getKey()),
                entry -> entry.getValue().stream().map(this::transcribeImplication).collect(Collectors.toSet())));
    }
    
    
    
    private TypeJudgement transcribeImplication(InputKeyImplication inputKeyImplication) {
        return new TypeJudgement(
                inputKeyImplication.getImpliedKey(), 
                transcribeVariablesToTuple(inputKeyImplication.getImpliedIndices())
        );
    }
    private Tuple transcribeVariablesToTuple(List<Integer> indices) {
        Object[] elements = new Object[indices.size()];
        for (int i = 0; i < indices.size(); ++i)
            elements[i] = variablesTuple.get(indices.get(i));
        return Tuples.flatTupleOf(elements);
    }

    @Override
    public String toString() {
        return "TypeJudgement:" + inputKey.getPrettyPrintableName() + "@" + variablesTuple.toString();
    }
    
    /**
     * Creates this judgement as a direct type constraint in the given PBody under construction.
     * <p> pre: the variables tuple must be formed of variables of that PBody.
     * @since 1.6
     */
    public PConstraint createConstraintFor(PBody pBody) {
        if (inputKey.isEnumerable()) {
            return new TypeConstraint(pBody, variablesTuple, inputKey);
        } else {
            return new TypeFilterConstraint(pBody, variablesTuple, inputKey);
        }
    }
}