-
Notifications
You must be signed in to change notification settings - Fork 1
/
Argument.java
129 lines (104 loc) · 3.33 KB
/
Argument.java
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
/*
* Argument.java
* -------------
* $Id: Argument.java,v 1.10 2000/11/17 01:35:37 chenli Exp $
*/
import java.util.*;
class Argument {
final public static int VAR = 0;
final public static int CONST = 1;
int type; // VAR or CONST
String name;
Argument(String name, boolean isConstant) {
if (name == null) {
UserLib.myerror("Argument:constructor, name == null");
}
// string starting with an upper-case char is a variable
if (Character.isUpperCase(name.charAt(0)))
type = VAR;
else
type = CONST;
if(isConstant)
type = CONST;
this.name = name;
}
Argument(String name) {
this(name, false);
}
/**
* Given a partial mapping phi, an HH, and a set of distinguished
* variables, checks whether this argument can be
* unified with a given argument by expanding the phihh. If so, phi and
* hh are extended correspondingly.
*/
public boolean unifiable(Argument arg, Mapping phi, Mapping hh,
Vector distVars) {
// we cannot map a constant to a different constant
if (this.isConst() && arg.isConst() && !this.equals(arg))
return false;
// two vars, checks the target of this arg in phi
Argument image = (Argument) phi.apply(this);
if (image == null) { // not mapped.
phi.put(this, arg); // adds the pair
return true;
}
// this arg has been mapped. checks if it has been mapped
// to the given arg
if (image.equals(arg)) return true;
// this arg was already mapped to a different arg. let's see if we can
// expand the hh to create this mapping
// first, the two args must both be distinguished
if ((!distVars.contains(image)) || (!distVars.contains(arg)))
return false;
// We don't allow constants to appear in the head
if (image.isConst() || arg.isConst()) {
System.out.println("Argument.unifiable(). We don't allow " +
"constants to be in a view's head.");
System.exit(1);
}
// equates these two args if the new arg has not been equated
if (hh.apply(arg) == null) hh.put(arg, image);
return true;
}
/**
* renames this argument to generate a new argument
*/
public Argument rename(int newId, Map argMap) {
if (argMap.containsKey(this))
return ((Argument) argMap.get(this));
return new Argument(name + "_" + newId); // a new name
}
public String getName() {
return name;
}
public int getType() {
return type;
}
public boolean isConst() {
return type == CONST;
}
/**
* Indicates whether some other argument is "equal to" this one.
* Notice that the parameter must be an "Object" class in order to
* override Object.equals(), not an "Argument" class.
*
* @param argument The reference object with which to compare.
* @return <code>true(false)</code> if this item is the same(not same) as
* the argument.
*/
public boolean equals(Object argument){
Argument arg = (Argument) argument;
return this.getName().equalsIgnoreCase(arg.getName())
&& this.getType() == arg.getType();
}
/**
* Overrides the hash function Object.hasCode(). As an item in a
* HashSet collection, called when HashSet.equals() is called.
*/
public int hashCode() {
return (type * 10000 + name.hashCode());
}
public String toString() {
return getName();
}
}