aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/PConstraintInfo.java
blob: c2c76ef27f6fb3003a7059c69fc87deee07769fa (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
/** 
 * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Danil 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.localsearch.planner;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Function;

import tools.refinery.viatra.runtime.localsearch.planner.cost.IConstraintEvaluationContext;
import tools.refinery.viatra.runtime.matchers.backend.ResultProviderRequestor;
import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext;
import tools.refinery.viatra.runtime.matchers.context.IQueryResultProviderAccess;
import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext;
import tools.refinery.viatra.runtime.matchers.psystem.PBody;
import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
import tools.refinery.viatra.runtime.matchers.psystem.analysis.QueryAnalyzer;

/** 
 * Wraps a PConstraint together with information required for the planner. Currently contains information about the expected binding state of
 * the affected variables also called application condition, and the cost of the enforcement, based on the meta and/or the runtime context.
 *  
 * @author Marton Bur
 * @noreference This class is not intended to be referenced by clients.
 */
public class PConstraintInfo implements IConstraintEvaluationContext {

    private PConstraint constraint;
    private Set<PVariable> boundMaskVariables;
    private Set<PVariable> freeMaskVariables;
    private Set<PConstraintInfo> sameWithDifferentBindings;
    private IQueryRuntimeContext runtimeContext;
    private QueryAnalyzer queryAnalyzer;
    private IQueryResultProviderAccess resultProviderAccess;
    private ResultProviderRequestor resultRequestor;

    private Double cost;
    private Function<IConstraintEvaluationContext, Double> costFunction;
    

    /** 
     * Instantiates the wrapper
     * @param constraintfor which the information is added and stored
     * @param boundMaskVariables the bound variables in the operation mask
     * @param freeMaskVariables the free variables in the operation mask
     * @param sameWithDifferentBindings during the planning process, multiple operation adornments are considered for a constraint, so that it
     * is represented by multiple plan infos. This parameter contains all plan infos that are for the same
     * constraint, but with different adornment
     * @param context the query backend context
     */
    public PConstraintInfo(PConstraint constraint, Set<PVariable> boundMaskVariables, Set<PVariable> freeMaskVariables,
        Set<PConstraintInfo> sameWithDifferentBindings, 
        IQueryBackendContext context,
        ResultProviderRequestor resultRequestor,
        Function<IConstraintEvaluationContext, Double> costFunction) {
        this.constraint = constraint;
        this.costFunction = costFunction;
        this.boundMaskVariables = new LinkedHashSet<>(boundMaskVariables);
        this.freeMaskVariables = new LinkedHashSet<>(freeMaskVariables);
        this.sameWithDifferentBindings = sameWithDifferentBindings;
        this.resultRequestor = resultRequestor;
        this.runtimeContext = context.getRuntimeContext();
        this.queryAnalyzer = context.getQueryAnalyzer();
        this.resultProviderAccess = context.getResultProviderAccess();

        this.cost = null; // cost will be computed lazily (esp. important for pattern calls)
    }
    
    @Override
    public IQueryRuntimeContext getRuntimeContext() {
        return runtimeContext;
    }

    @Override
    public QueryAnalyzer getQueryAnalyzer() {
        return queryAnalyzer;
    }

    @Override
    public PConstraint getConstraint() {
        return constraint;
    }

    @Override
    public Set<PVariable> getFreeVariables() {
        return freeMaskVariables;
    }

    @Override
    public Set<PVariable> getBoundVariables() {
        return boundMaskVariables;
    }

    public Set<PConstraintInfo> getSameWithDifferentBindings() {
        return sameWithDifferentBindings;
    }

    public double getCost() {
        if (cost == null) {
            // Calculate cost of the constraint based on its type
            cost = costFunction.apply(this);
        }
        return cost;
    }

    public PConstraintCategory getCategory(PBody pBody, Set<PVariable> boundVariables) {
        if (!Collections.disjoint(boundVariables, this.freeMaskVariables)) {
            return PConstraintCategory.PAST;
        } else if (!boundVariables.containsAll(this.boundMaskVariables)) {
            return PConstraintCategory.FUTURE;
        } else {
            return PConstraintCategory.PRESENT;
        }
    }

    @Override
    public String toString() {
        return String.format("%s, bound variables: %s, cost: \"%.2f\"", constraint.toString(), boundMaskVariables.toString(), cost);
    }

    /**
     * @deprecated use {@link #resultProviderRequestor()}
     */
    @Override
    @Deprecated
    public IQueryResultProviderAccess resultProviderAccess() {
        return resultProviderAccess;
    }
    
    @Override
    public ResultProviderRequestor resultProviderRequestor() {
        return resultRequestor;
    }

}