@@ -698,19 +698,67 @@ def valid_coordinates(self, *coordinates, **kwds):
698698 substitutions = dict (zip (self ._xx , coordinates ))
699699 if parameters :
700700 substitutions .update (parameters )
701- for restrict in self ._restrictions :
702- if isinstance (restrict , tuple ): # case of or conditions
703- combine = False
704- for expr in restrict :
705- combine = combine or bool (expr .subs (substitutions ))
706- if not combine :
707- return False
708- else :
709- if not bool (restrict .subs (substitutions )):
710- return False
711- # All tests have been passed:
701+ return self ._check_restrictions (self ._restrictions , substitutions )
712702 return True
713703
704+ def _check_restrictions (self , restrict , substitutions ):
705+ r"""
706+ Recursive helper function to check the validity of coordinates
707+ given some restrictions
708+
709+ INPUT:
710+
711+ - restrict: a tuple of conditions (combined with 'or'), a list of
712+ conditions (combined with 'and') or a single coordinate condition
713+ - substitutions: dictionary (keys: coordinates of ``self``) giving the
714+ value of each coordinate
715+
716+ OUTPUT:
717+
718+ - boolean stating whether the conditions are fulfilled by the
719+ coordinate values
720+
721+ TESTS::
722+
723+ sage: M = Manifold(2, 'M', structure='topological')
724+ sage: X.<x,y> = M.chart()
725+ sage: X._check_restrictions(x>0, {x: pi, y: 0})
726+ True
727+ sage: X._check_restrictions(x>0, {x: -sqrt(2), y: 0})
728+ False
729+ sage: X._check_restrictions((x>0, [x<y, y<0]), {x: 1, y: 2})
730+ True
731+ sage: X._check_restrictions((x>0, [x<y, y<0]), {x: -1, y: 2})
732+ False
733+ sage: X._check_restrictions((x>0, [x<y, y<0]), {x: -1, y: -1/2})
734+ True
735+ sage: X._check_restrictions([(x<y, y<0), x>0], {x: 1, y: 2})
736+ True
737+ sage: X._check_restrictions([(x<y, y<0), x>0], {x: -1, y: 2})
738+ False
739+ sage: X._check_restrictions([(x<y, y<0), x>0], {x: 1, y: -2})
740+ True
741+ sage: X._check_restrictions([(x<y, y<0), x>0], {x: 2, y: 1})
742+ False
743+
744+ """
745+ if isinstance (restrict , tuple ): # case of 'or' conditions
746+ combine = False
747+ for cond in restrict :
748+ combine = combine or self ._check_restrictions (cond ,
749+ substitutions )
750+ return combine
751+ elif isinstance (restrict , list ): # case of 'and' conditions
752+ combine = True
753+ for cond in restrict :
754+ combine = combine and self ._check_restrictions (cond ,
755+ substitutions )
756+ return combine
757+ # Case of a single condition:
758+ return bool (restrict .subs (substitutions ))
759+
760+
761+
714762 def transition_map (self , other , transformations , intersection_name = None ,
715763 restrictions1 = None , restrictions2 = None ):
716764 r"""
@@ -1633,8 +1681,8 @@ def add_restrictions(self, restrictions):
16331681 for restrict in self ._restrictions :
16341682 restrict_used = False # determines whether restrict is used
16351683 # to set some coordinate bound
1636- if not isinstance (restrict , tuple ) : # case of 'or' conditions
1637- # excluded
1684+ if not isinstance (restrict , ( tuple , list )) : # case of combined
1685+ # conditions excluded
16381686 operands = restrict .operands ()
16391687 left = operands [0 ]
16401688 right = operands [1 ]
@@ -1812,6 +1860,20 @@ def valid_coordinates(self, *coordinates, **kwds):
18121860 sage: XD.valid_coordinates(0,0)
18131861 True
18141862
1863+ Another open subset of the square, defined by `x^2+y^2<1` or
1864+ (`x>0` and `|y|<1`)::
1865+
1866+ sage: B = M.open_subset('B',
1867+ ....: coord_def={X: (x^2+y^2<1,
1868+ ....: [x>0, abs(y)<1])})
1869+ sage: XB = X.restrict(B)
1870+ sage: XB.valid_coordinates(-1/2, 0)
1871+ True
1872+ sage: XB.valid_coordinates(-1/2, 3/2)
1873+ False
1874+ sage: XB.valid_coordinates(3/2, 1/2)
1875+ True
1876+
18151877 """
18161878 n = len (coordinates )
18171879 if n != self ._manifold ._dim :
@@ -1836,31 +1898,19 @@ def valid_coordinates(self, *coordinates, **kwds):
18361898 if min_included :
18371899 if x < xmin :
18381900 return False
1839- else :
1840- if x <= xmin :
1841- return False
1901+ elif x <= xmin :
1902+ return False
18421903 if max_included :
18431904 if x > xmax :
18441905 return False
1845- else :
1846- if x >= xmax :
1847- return False
1906+ elif x >= xmax :
1907+ return False
18481908 # Check of additional restrictions:
1849- if self ._restrictions != [] :
1909+ if self ._restrictions :
18501910 substitutions = dict (zip (self ._xx , coordinates ))
18511911 if parameters :
18521912 substitutions .update (parameters )
1853- for restrict in self ._restrictions :
1854- if isinstance (restrict , tuple ): # case of or conditions
1855- combine = False
1856- for expr in restrict :
1857- combine = combine or bool (expr .subs (substitutions ))
1858- if not combine :
1859- return False
1860- else :
1861- if not bool (restrict .subs (substitutions )):
1862- return False
1863- # All tests have been passed:
1913+ return self ._check_restrictions (self ._restrictions , substitutions )
18641914 return True
18651915
18661916 @options (max_range = 8 , color = 'red' , style = '-' , thickness = 1 , plot_points = 75 ,
0 commit comments