Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

r""" 

Facade Sets 

 

For background, see :ref:`What is a facade set? <facade-sets>`. 

""" 

#***************************************************************************** 

# Copyright (C) 2010-2011 Nicolas M. Thiery <nthiery at users.sf.net> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# http://www.gnu.org/licenses/ 

#****************************************************************************** 

 

from sage.categories.category_with_axiom import CategoryWithAxiom 

 

class FacadeSets(CategoryWithAxiom): 

def example(self, choice='subset'): 

r""" 

Returns an example of facade set, as per 

:meth:`Category.example() 

<sage.categories.category.Category.example>`. 

 

INPUT: 

 

- ``choice`` -- 'union' or 'subset' (default: 'subset'). 

 

EXAMPLES:: 

 

sage: Sets().Facade().example() 

An example of facade set: the monoid of positive integers 

sage: Sets().Facade().example(choice='union') 

An example of a facade set: the integers completed by +-infinity 

sage: Sets().Facade().example(choice='subset') 

An example of facade set: the monoid of positive integers 

""" 

import sage.categories.examples.facade_sets as examples 

if choice == "union": 

return examples.IntegersCompletion() 

elif choice == 'subset': 

return examples.PositiveIntegerMonoid() 

else: 

raise TypeError("choice should be 'union' or 'subset'") 

 

class ParentMethods: 

 

def _element_constructor_(self, element): 

""" 

Coerce ``element`` into ``self`` 

 

INPUT: 

 

- ``element`` -- any object 

 

This default implementation returns ``element`` if 

``self`` is a facade for ``parent(element)`. Otherwise it 

attempts in turn to coerce ``element`` into each parent 

``self`` is a facade for. 

 

This implementation is only valid for a facade parent 

which models the full union of the parents it is a facade 

for. Other facade parents should redefine 

:meth:`element_constructor` appropriately. 

 

EXAMPLES:: 

 

sage: S = Sets().Facade().example("union"); S 

An example of a facade set: the integers completed by +-infinity 

sage: S(1) 

1 

sage: S(1/2) 

Traceback (most recent call last): 

... 

ValueError: Can't coerce `1/2` in any parent `An example of a facade set: the integers completed by +-infinity` is a facade for 

sage: S(2/1) 

2 

sage: S(2/1).parent() 

Integer Ring 

sage: S(int(1)) 

1 

sage: S(int(1)).parent() 

Integer Ring 

 

Facade parents that model strict subsets should redefine 

:meth:`element_constructor`:: 

 

sage: S = Sets().Facade().example(); S 

An example of facade set: the monoid of positive integers 

sage: S(-1) 

Traceback (most recent call last): 

... 

ValueError: %s should be positive 

""" 

if self.is_parent_of(element): 

return element 

else: 

parents = self.facade_for() 

if parents is True: 

raise NotImplementedError 

for parent in self.facade_for(): 

try: 

return parent(element) 

except Exception: 

pass 

raise ValueError("Can't coerce `%s` in any parent `%s` is a facade for"%(element, self)) 

 

def facade_for(self): 

""" 

Returns the parents this set is a facade for 

 

This default implementation assumes that ``self`` has 

an attribute ``_facade_for``, typically initialized by 

:meth:`Parent.__init__`. If the attribute is not present, the method 

raises a NotImplementedError. 

 

EXAMPLES:: 

 

sage: S = Sets().Facade().example(); S 

An example of facade set: the monoid of positive integers 

sage: S.facade_for() 

(Integer Ring,) 

 

Check that :trac:`13801` is corrected:: 

 

sage: class A(Parent): 

....: def __init__(self): 

....: Parent.__init__(self, category=Sets(), facade=True) 

sage: a = A() 

sage: a.facade_for() 

Traceback (most recent call last): 

... 

NotImplementedError: this parent did not specify which parents it is a facade for 

""" 

try: 

return self._facade_for 

except AttributeError: 

raise NotImplementedError("this parent did not specify which parents it is a facade for") 

 

def is_parent_of(self, element): 

""" 

Returns whether ``self`` is the parent of ``element`` 

 

INPUT: 

 

- ``element`` -- any object 

 

Since ``self`` is a facade domain, this actually tests 

whether the parent of ``element`` is any of the parent 

``self`` is a facade for. 

 

EXAMPLES:: 

 

sage: S = Sets().Facade().example(); S 

An example of facade set: the monoid of positive integers 

sage: S.is_parent_of(1) 

True 

sage: S.is_parent_of(1/2) 

False 

 

This method differs from :meth:`__contains__` in two 

ways. First, this does not take into account the fact 

that ``self`` may be a strict subset of the parent(s) 

it is a facade for:: 

 

sage: -1 in S, S.is_parent_of(-1) 

(False, True) 

 

Furthermore, there is no coercion attempted:: 

 

sage: int(1) in S, S.is_parent_of(int(1)) 

(True, False) 

 

.. warning:: 

 

this implementation does not handle facade parents of facade 

parents. Is this a feature we want generically? 

""" 

parents = self.facade_for() 

if parents is True: 

return True 

from sage.structure.element import parent 

return parent(element) in parents 

 

def __contains__(self, element): 

""" 

Membership testing 

 

Returns whether ``element`` is in one of the parents 

``self`` is a facade for. 

 

.. warning:: this default implementation is currently 

overriden by :meth:`Parent.__contains__`. 

 

EXAMPLES:: 

 

sage: S = Sets().Facade().example("union"); S 

An example of a facade set: the integers completed by +-infinity 

sage: 1 in S, -5 in S, oo in S, -oo in S, int(1) in S, 2/1 in S 

(True, True, True, True, True, True) 

sage: 1/2 in S, "bla" in S 

(False, False) 

""" 

return any(element in parent for parent in self.facade_for()) 

 

def _an_element_(self): 

""" 

Try to return an element of ``self``, as per 

:meth:`Sets.ParentMethods.an_element`. 

 

For each parent ``self`` is a facade for, this default 

implementation tries the method ``an_element`` until it finds an 

element in ``self``. If none is found raise a 

``NotImplementedError``. 

 

EXAMPLES:: 

 

sage: S = Sets().Facade().example(); S 

An example of facade set: the monoid of positive integers 

sage: S.an_element() 

1 

""" 

for parent in self.facade_for(): 

x = parent.an_element() 

if x in self: 

return x 

raise NotImplementedError