Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / math / Operations.java @ 12

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.math;
29

    
30
import org.momut.ooas.ast.expressions.ExpressionKind;
31
import org.momut.ooas.utils.exceptions.ArgumentException;
32
import org.momut.ooas.utils.exceptions.NotImplementedException;
33

    
34
public class Operations<T> extends AbstractOperations
35
{
36
        public static class BasicOps<T> {
37
                public T unMinus(T input) {throw new NotImplementedException();}
38

    
39
                public T minus(T inputA, T inputB) {throw new NotImplementedException();}
40
                public T plus(T inputA, T inputB) {throw new NotImplementedException();}
41
                public T div(T inputA, T inputB) {throw new NotImplementedException();}
42
                public T pow(T inputA, T inputB) {throw new NotImplementedException();}
43
                public T prod(T inputA, T inputB) {throw new NotImplementedException();}
44
                public T mod(T inputA, T inputB) {throw new NotImplementedException();}
45

    
46
                public boolean equal(T inputA, T intputB) {throw new NotImplementedException();}
47
                public boolean smaller(T inputA, T intputB) {throw new NotImplementedException();}
48
                public boolean greater(T inputA, T intputB){throw new NotImplementedException();}
49

    
50
                public T getDefaultValue() {throw new NotImplementedException();}
51
        }
52

    
53
        protected final BasicOps<T> m_basicOperations;
54

    
55

    
56
        @SuppressWarnings("unchecked")
57
        @Override
58
        public AbstractRange GenericArithmeticCover(AbstractRange type1, AbstractRange type2, ExpressionKind op)
59
        {
60
                final Range<T> a = (Range<T>) type1;
61
                final Range<T> b = (Range<T>) type2;
62

    
63
//                Range<T> a = type1 as Range<T>;
64
//                Range<T> b = type2 as Range<T>;
65

    
66
                if (a == null || b == null)
67
                        throw new ArgumentException();
68

    
69
                return GenericArithmeticCover(a, b, op);
70
        }
71

    
72
        public Range<T> GenericArithmeticCover(Range<T> type1, Range<T> type2, ExpressionKind op)
73
        {
74
                final T defaultValue = m_basicOperations.getDefaultValue();
75
                final Range<T> result = type1.Create(defaultValue, defaultValue);
76

    
77
                switch (op)
78
                {
79
                        case unminus:
80
                                result.min = m_basicOperations.unMinus(type1.max);
81
                                result.max = m_basicOperations.unMinus(type1.min);
82
                                break;
83
                        case unplus:
84
                                break;
85

    
86
                        case minus:
87
                                assert(type2 != null);
88
                                // we do some sort of resulttype = type1 - type2
89
                                // hence, do the unminus stuff with type 2
90
                                final T spare = type2.max;
91
                                type2.max = m_basicOperations.unMinus(type2.min);
92
                                type2.min = m_basicOperations.unMinus(spare);
93
                                // now it's the same as with sum.. but c# does not let us fall through..
94
                                result.min = m_basicOperations.plus(type1.min, type2.min);
95
                                result.max = m_basicOperations.plus(type1.max, type2.max);
96
                                break;
97
                        case sum:
98
                                assert(type2 != null);
99
                                result.min = m_basicOperations.plus(type1.min, type2.min);
100
                                result.max = m_basicOperations.plus(type1.max, type2.max);
101
                                break;
102
                        case idiv:
103
                        case div:
104
                                // get the closest values to 0 for the divisor.
105
                                assert(type2 != null);
106
                                final Range<T> closestToZero = type2.Create(defaultValue, defaultValue);
107
                                if (m_basicOperations.greater(type2.max, defaultValue) && (m_basicOperations.greater(type2.min, defaultValue) || m_basicOperations.equal(type2.min, defaultValue))) {
108
                                        // divisor range [X...0+]
109
                                        closestToZero.max = m_basicOperations.equal(type2.min, defaultValue) ? type2.precision : type2.min; // type2.min or type2.precision if that was 0
110
                                        closestToZero.min = closestToZero.max;
111
                                } else if (m_basicOperations.smaller(type2.max, defaultValue) && (m_basicOperations.smaller(type2.min, defaultValue) || m_basicOperations.equal(type2.min, defaultValue))) {
112
                                        // divisor range [0-...-X]
113
                                        closestToZero.max = m_basicOperations.equal(type2.min, defaultValue) ? m_basicOperations.unMinus(type2.precision) : type2.min; // type2.min or -type2.precision if that was 0
114
                                        closestToZero.min = closestToZero.max;
115
                                } else {
116
                                        // divisor range [Y ... -X]
117
                                        closestToZero.max = type2.precision;
118
                                        closestToZero.min = m_basicOperations.unMinus(type2.precision);
119
                                }
120

    
121
                                result.max = m_basicOperations.div(type1.min, closestToZero.min);
122
                                result.min = result.max;
123

    
124
                                T tmp = m_basicOperations.div(type1.max, closestToZero.min);
125
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
126
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
127

    
128
                                tmp = m_basicOperations.div(type1.min, closestToZero.max);
129
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
130
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
131

    
132
                                tmp = m_basicOperations.div(type1.max, closestToZero.max);
133
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
134
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
135
                                break;
136
                        case mod:
137
                                throw new ArgumentException(); // do this one level up
138
                        case pow:
139
                                // ok, this is bad. - just give up here
140
                                result.max = result.typemax;
141
                                result.min = result.typemin;
142
                                break;
143
                        case prod:
144
                                // hmm, brute force.. is there some formula?
145
                                result.max = m_basicOperations.prod(type1.min, type2.min);
146
                                result.min = result.max;
147

    
148
                                tmp = m_basicOperations.prod(type1.max, type2.min);
149
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
150
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
151

    
152
                                tmp = m_basicOperations.prod(type1.min, type2.max);
153
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
154
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
155

    
156
                                tmp = m_basicOperations.prod(type1.max, type2.max);
157
                                result.max = m_basicOperations.smaller(result.max, tmp) ? tmp : result.max;
158
                                result.min = m_basicOperations.greater(result.min, tmp) ? tmp : result.min;
159
                                break;
160

    
161
                        default:
162
                                throw new NotImplementedException();
163
                }
164
                return result;
165
        }
166

    
167

    
168
        public Operations()
169
        {
170
                m_basicOperations = new BasicOps<T>();
171
        }
172

    
173
        public Operations(BasicOps<T> basicOperations)
174
        {
175
                m_basicOperations = basicOperations;
176
        }
177
}