Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
[no subject]
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  13 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:26 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject:
this introduces my work on the new assumption system. The old assumption is left
untouched until we migrate all the code the new assumption system.

you can pull from http://fseoane.net/git/sympy.git, branch proposed


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "implement get_class and get_mod_func in sympy.utilities.source" by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:28 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject: [PATCH 2/5] implement get_class and get_mod_func in sympy.utilities.source
Function get_class returns a class from a given string. It makes use
of get_mod_func
---
 sympy/utilities/source.py |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/sympy/utilities/source.py b/sympy/utilities/source.py
index 56ca7f7..1470759 100644
--- a/sympy/utilities/source.py
+++ b/sympy/utilities/source.py
@@ -10,3 +10,29 @@ def source(object):
     """
     print 'In file: %s' % inspect.getsourcefile(object)
     print inspect.getsource(object)
+
+def get_class(lookup_view):
+    """
+    Convert a string version of a class name to the object.
+
+    This is used by the query method
+    """
+    if isinstance(lookup_view, str):
+        # Bail early for non-ASCII strings (they can't be functions).
+        lookup_view = lookup_view.encode('ascii')
+        mod_name, func_name = get_mod_func(lookup_view)
+        if func_name != '':
+            lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name)
+            if not callable(lookup_view):
+                raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name))
+    return lookup_view
+
+
+def get_mod_func(callback):
+    # Converts 'sympy.core.query.QueryIntegerHandler' to
+    # ['sympy.core.query', 'QueryIntegerHandler']
+    try:
+        dot = callback.rindex('.')
+    except ValueError:
+        return callback, ''
+    return callback[:dot], callback[dot+1:]
\ No newline at end of file
--
1.6.1.2


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "implement backward-chaining for propositional logic in core.facts." by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:29 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject: [PATCH 3/5] implement backward-chaining for propositional logic in core.facts.
This is a very naive implementation. It constructs EVERY possible query
with propositions from self.defined_facts and tries every one to see
if it succeeds.

It has unacceptable slow performance. This is implemented just as
workaround for the new assumption system, but eventually a complete
backward-chaining algorithm should be implemented.
---
 sympy/core/facts.py                  |   42 ++++++++++++++++++++++++++++++++++
 sympy/core/tests/test_assumptions.py |   28 +++++++++++++++++++++-
 sympy/core/tests/test_facts.py       |   10 ++++++++
 3 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/sympy/core/facts.py b/sympy/core/facts.py
index 2e9d666..27bf0c6 100644
--- a/sympy/core/facts.py
+++ b/sympy/core/facts.py
@@ -817,6 +817,48 @@ def __init__(self, rules):
     # TODO: add proper support for U (None), i.e.
     #       integer=U  -> rational=U  ??? (XXX i'm not sure)

+    def bc_ask(self, goal, theta={}):
+        """Backward-chaining algorithm. Backward-chaining reasoners process
+        queries and return proofs for the answers they provide.
+
+        This is a very naive implementation. It constructs EVERY possible query
+        with propositions from self.defined_facts and tries every one to see
+        if it succeeds.
+
+        It has unacceptable slow performance. This is implemented just as
+        workaround for the new assumption system. Do *NOT* commit to the
+        main repo
+        """
+
+        if len(goal.keys()) > 1:
+            raise NotImplementedError
+
+        key = goal.keys()[0]
+        _facts = []
+        from sympy.utilities.iterables import subsets, variations
+        for k in range(len(self.defined_facts)):
+            k_subsets = list(subsets(self.defined_facts, k))
+            for k_sub in k_subsets:
+                if not key in k_sub:
+                    # it won't be of any use if goal is in answers
+                    for _pos in variations([True, False], len(k_sub), repetition=True):
+                        _res = dict()
+                        for k, i in enumerate(k_sub):
+                            _res[i] = _pos[k]
+                        _facts.append(_res)
+
+        answers = []
+        for _f in _facts:
+            try:
+                _deduced = self.deduce_all_facts(_f)
+
+                if _deduced.has_key(key) and _deduced[key] == goal[key]:
+                    answers.append(_f)
+            except AssertionError:
+                pass
+
+        return answers
+

     def deduce_all_facts(self, facts, base=None):
         """Deduce all facts from known facts ({} or [] of (k,v))
diff --git a/sympy/core/tests/test_assumptions.py b/sympy/core/tests/test_assumptions.py
index cb1c0d5..a4d7ca8 100644
--- a/sympy/core/tests/test_assumptions.py
+++ b/sympy/core/tests/test_assumptions.py
@@ -1,4 +1,30 @@
-from sympy.core import Symbol, S, Rational, Integer
+from sympy.core.assumptions import Assume
+from sympy.core import Symbol
+
+def test_assume():
+    x = Symbol('x')
+    assump = Assume(x, 'integer')
+    assert assump.expr == x
+    assert assump.key == 'integer'
+    assert assump.bool_key == True
+
+def test_assume_False():
+    x = Symbol('x')
+    assump = Assume(x, 'integer', False)
+    assert assump.expr == x
+    assert assump.key == 'integer'
+    assert assump.bool_key == False
+
+def test_assume_equal():
+    x = Symbol('x')
+    assert Assume(x, 'positive') == Assume(x, 'positive')
+    assert Assume(x, 'positive') != Assume(x, 'positive', False)
+    assert Assume(x, 'positive', False) == Assume(x, 'positive', False)
+
+### Also check the old assumption system until it is completely
+### removed
+
+from sympy.core import S, Rational, Integer
 from sympy.utilities.pytest import XFAIL, raises

 def test_symbol_unset():
diff --git a/sympy/core/tests/test_facts.py b/sympy/core/tests/test_facts.py
index b86346f..f7a129e 100644
--- a/sympy/core/tests/test_facts.py
+++ b/sympy/core/tests/test_facts.py
@@ -335,3 +335,13 @@ def X_test_FactRules_deduce_cow():

     assert X == {'real': T, 'neg': F, 'zero': F, 'pos': T}
     #assert set(new_knowledge) == set([ ('zero',F), ('pos',T) ])    # XXX disabled
+
+def test_bc_ask():
+    # test backward chaining
+    f = FactRules(['negative   == real & !zero & !pos'])
+    f.bc_ask({'negative' : True}) == [{'pos': False, 'real': True, 'zero': False}]
+    f = FactRules(['Odd -> Integer'])
+    f.bc_ask({'Integer' : True}) == {'Odd':True, 'Integer':True}
+
+    f = FactRules(['positive ==  real & !negative & !zero'])
+    f.bc_ask({'positive' : True}) == {'negative' : False, 'real' : True, 'zero' : False}
--
1.6.1.2


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Implement variations in sympy.utilities.iterables" by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:27 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject: [PATCH 1/5] Implement variations in sympy.utilities.iterables
variations is a routine that calculates all possible variations
of size n (with or without repetition) of a given set.
---
 sympy/utilities/iterables.py            |   36 +++++++++++++++++++++++++++++++
 sympy/utilities/tests/test_iterables.py |    6 ++++-
 2 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/sympy/utilities/iterables.py b/sympy/utilities/iterables.py
index 6179622..61879a6 100644
--- a/sympy/utilities/iterables.py
+++ b/sympy/utilities/iterables.py
@@ -173,3 +173,39 @@ def recursion(result, M, k):
         for elem in recursion([item], M[i + 1:], k - 1):
             yield elem

+
+def cartes(seq0, seq1, modus='pair'):
+    """ return the Cartesian Product of two sequences """
+    if  modus == 'pair':
+        return [[item0, item1] for item0 in seq0 for item1 in seq1]
+    elif modus == 'triple':
+        return [item0 + [item1] for item0 in seq0 for item1 in seq1]
+
+def variations(seq, n, repetition=False):
+    """Returns all the variations of the list of size n.
+
+    variations(seq, n, True) will return all the variations of the list of
+        size n with repetitions
+
+    variations(seq, n, False) will return all the variations of the list of
+        size n without repetitions
+    """
+    def setrep(seq):  # remove sets with duplicates (repetition is relevant)
+        def delrep(seq):  # remove duplicates while maintaining order
+            result = []
+            for item in seq:
+                if item not in result:
+                    result.append(item)
+            return result
+        return [item for item in seq if item == delrep(item)]
+
+    if n == 1:
+        return [[item] for item in seq]
+    result = range(len(seq))
+    cartesmodus = 'pair'
+    for i in range(n-1):
+        result = cartes(result, range(len(seq)), cartesmodus)
+        if not repetition:
+            result = setrep(result)
+        cartesmodus = 'triple'
+    return [[seq[index] for index in indices] for indices in result]
diff --git a/sympy/utilities/tests/test_iterables.py b/sympy/utilities/tests/test_iterables.py
index 1eea497..959c900 100644
--- a/sympy/utilities/tests/test_iterables.py
+++ b/sympy/utilities/tests/test_iterables.py
@@ -1,6 +1,6 @@
 from sympy import symbols
 from sympy.utilities.iterables import postorder_traversal, \
-    preorder_traversal, flatten, subsets
+    preorder_traversal, flatten, subsets, variations

 w,x,y,z= symbols('wxyz')
@@ -31,3 +31,7 @@ def test_subsets():
     assert list(subsets([1, 2, 3], 2)) == [[1, 2], [1,3], [2, 3]]
     assert list(subsets([1, 2, 3], 3)) == [[1, 2, 3]]

+def test_variations():
+    assert variations([1,2,3], 2) == [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
+    assert variations([1,2,3], 2, True) == [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], \
+                        [3,1], [3,2], [3,3]]
--
1.6.1.2


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Implement new assumption framework." by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:30 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject: [PATCH 4/5] Implement new assumption framework.
The old assumption system had some limitations:

    1. Can't assume relations. It is not possible to specify relations between different
        objects. For example, you can assume that x>0 and y>0, but you can't
        assume x>y

    2. Verbose code splitted across multiple classes. Each class must override
        query methods (.is_*).

    3. Extensibility. To add new assumptions you have to add code to
        the core

The assumption system implemented in this series of patches relies on these
principles:

    1. Assumptions are separate from objects. Assumptions are instances of Assume, which is
       a class that holds a reference to the expression and to the 'key' (what it assumes)

    2. Queries out of the core. No more .is_* methods. Specific queries are implemented
        as subclasses of QueryHandler, and the query function calls the appropriate
        subclass of QueryHandler

        query -> QueryHandler -> QueryNegativeHandler
                              -> QueryIntegerHandler
                              -> QueryBoundedHandler
                              ...
       That way, creating new queries is a matter of subclassing QueryHandler and override
       the apropriate methods.

In this patch, two fundamental objects were created for this task:

  - sympy.core.assumptions.Assume, which takes track of the
    object's assumptions.

  - a query method: sympy.query.query, which replaces the old
    expr.is_* syntax. Also the relevat handlers were created to resolve
    some queries, in sympy.queries.handlers

The old assumptions system was not modified, but should be removed
gradually
---
 sympy/__init__.py                |    1 +
 sympy/core/__init__.py           |    1 +
 sympy/core/assumptions.py        |   37 +++
 sympy/query/__init__.py          |  154 ++++++++++
 sympy/query/handlers/__init__.py |  169 +++++++++++
 sympy/query/handlers/calculus.py |  125 ++++++++
 sympy/query/handlers/ntheory.py  |   63 ++++
 sympy/query/handlers/order.py    |  168 +++++++++++
 sympy/query/handlers/sets.py     |  239 +++++++++++++++
 sympy/query/tests/test_query.py  |  594 ++++++++++++++++++++++++++++++++++++++
 10 files changed, 1551 insertions(+), 0 deletions(-)
 create mode 100644 sympy/query/__init__.py
 create mode 100644 sympy/query/handlers/__init__.py
 create mode 100644 sympy/query/handlers/calculus.py
 create mode 100644 sympy/query/handlers/ntheory.py
 create mode 100644 sympy/query/handlers/order.py
 create mode 100644 sympy/query/handlers/sets.py
 create mode 100644 sympy/query/tests/test_query.py

diff --git a/sympy/__init__.py b/sympy/__init__.py
index b0b637f..3cef873 100644
--- a/sympy/__init__.py
+++ b/sympy/__init__.py
@@ -33,6 +33,7 @@ def __sympy_debug():
 from geometry import *
 from utilities import *
 from integrals import *
+from query import query
 # This module is slow to import:
 #from physics import units
 from plotting import Plot, textplot
diff --git a/sympy/core/__init__.py b/sympy/core/__init__.py
index 6b9355e..0fd8976 100644
--- a/sympy/core/__init__.py
+++ b/sympy/core/__init__.py
@@ -15,6 +15,7 @@
     Function, expand, PoleError
 from interval import Interval
 from evalf import PrecisionExhausted, N
+from assumptions import Assume

 # expose singletons like exp, log, oo, I, etc.
 for _n, _cls in Basic.singleton.items():
diff --git a/sympy/core/assumptions.py b/sympy/core/assumptions.py
index e8a9fd6..c528cfc 100644
--- a/sympy/core/assumptions.py
+++ b/sympy/core/assumptions.py
@@ -372,3 +372,40 @@ def getit(self):
     #dis(getit)

     return getit
+
+
+class Assume(object):
+    """New-style assumptions
+
+    >>> from sympy import Symbol, Assume
+    >>> x = Symbol('x')
+    >>> Assume(x, 'integer')
+    Assume( x, integer, True )
+    >>> Assume(x, 'integer', False)
+    Assume( x, integer, False )
+    """
+
+    def __init__(self, expr, key, bool_key=True):
+        if not expr.__class__.__name__ == "Symbol":
+            raise NotImplementedError
+        self._args = (expr, key, bool_key)
+
+    @property
+    def expr(self):
+        return self._args[0]
+
+    @property
+    def key(self):
+        return self._args[1]
+
+    @property
+    def bool_key(self):
+        return self._args[2]
+
+    def __repr__(self):
+        return u"Assume( %s, %s, %s )" % (self.expr, self.key, self.bool_key)
+
+    def __eq__(self, other):
+        if isinstance(other, type(self)):
+            return self._args == other._args
+        return False
diff --git a/sympy/query/__init__.py b/sympy/query/__init__.py
new file mode 100644
index 0000000..efcc891
--- /dev/null
+++ b/sympy/query/__init__.py
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+import copy
+import inspect
+from sympy.core import S
+from sympy.core.facts import FactRules
+from sympy.utilities.source import get_class
+
+# query_dict tells us what query handler we should use
+# for a particular key
+query_dict = {
+    'bounded'        : 'sympy.query.handlers.QueryBoundedHandler',
+    'commutative'    : 'sympy.query.handlers.QueryCommutativeHandler',
+    'comparable'     : 'sympy.query.handlers.QueryComparableHadler',
+    'complex'        : 'sympy.query.handlers.sets.QueryComplexHandler',
+    'composite'      : 'sympy.query.handlers.ntheory.QueryCompositeHandler',
+    'even'           : 'sympy.query.handlers.ntheory.QueryEvenHandler',
+    'finite'         : 'sympy.query.handlers.QueryFiniteHandler',
+    'imaginary'      : 'sympy.query.handlers.sets.QueryImaginaryHandler',
+    'infinitesimal'  : 'sympy.query.handlers.QueryInfinitesimalHandler',
+    'integer'        : 'sympy.query.handlers.sets.QueryIntegerHandler',
+    'irrational'     : 'sympy.query.handlers.sets.QueryIrrationalHandler',
+    'rational'       : 'sympy.query.handlers.sets.QueryRationalHandler',
+    'nonnegative'    : 'sympy.query.handlers.order.QueryNonNegativeHandler',
+    'noninteger'     : 'sympy.query.handlers.sets.QueryNonIntegerHandler',
+    'nonpositive'    : 'sympy.query.handlers.order.QueryNonPositiveHandler',
+    'nonzero'        : 'sympy.query.handlers.order.QueryNonZeroHandler',
+    'negative'       : 'sympy.query.handlers.order.QueryNegativeHandler',
+    'positive'       : 'sympy.query.handlers.order.QueryPositiveHandler',
+    'prime'          : 'sympy.query.handlers.ntheory.QueryPrimeHandler',
+    'real'           : 'sympy.query.handlers.sets.QueryRealHandler',
+    'odd'            : 'sympy.query.handlers.ntheory.QueryOddHandler',
+    'unbounded'      : 'sympy.query.handlers.QueryUnboundedHandler',
+    'zero'           : 'sympy.query.handlers.order.QueryZeroHandler'
+}
+
+
+def query(expr, key, assumptions=[], qdict={}, nesting=True):
+    """
+    Examples:
+    >>> query(2, 'negative')
+    False
+    >>> query(x + y, 'complex')
+    True
+    >>> query(x + y, 'real', Assume(x, 'real'))
+    True
+
+    Strategy:
+    - Phase 1: we call the handler for this key
+    - Phase 2: we try to deduce that the query is False by showing
+        that some prerequisite is not met
+    - Phase 3: try to deduce the query is True by showing that other requisite
+        that implies this queries does verify.
+    """
+    resolution = None
+    expr = S(expr)
+
+    if not isinstance(assumptions, (list, tuple)):
+        assumptions = [assumptions]
+
+    _assumptions = []
+    for assump in assumptions:
+        if expr.has(assump.expr):
+            # logic inference is expensive, so we only use the assumptions
+            # that are relevant
+            _assumptions.append(assump)
+
+    _query_dict = query_dict.copy()
+
+    if len(qdict) > 0:
+        _query_dict.update(qdict)
+
+    resolutor = get_class(_query_dict[key])(expr, key, _assumptions)
+
+    if resolutor.resolution is not None:
+        return resolutor.resolution
+
+    # Run this class handler
+    if hasattr(resolutor, expr.__class__.__name__):
+        resolution = getattr(resolutor, expr.__class__.__name__)()
+    else:
+        # we try for method defined for subclasses
+        mro = inspect.getmro(expr.__class__)
+        for subclass in mro:
+            if hasattr(resolutor, subclass.__name__):
+                resolution = getattr(resolutor, subclass.__name__)()
+                break
+        else:
+            # if no resolution maybe we could skip some steps
+            pass
+
+    if resolution is not None:
+        # if resolution is False or True there's no need to continue
+        return resolution
+
+    if not nesting:
+        return None
+
+    if resolutor.facts is None:
+        # initialize facts
+        facts = []
+    else:
+        facts = copy.copy(resolutor.facts)
+    # add to self.facts all the assumption's facts
+    # so we get a tree that connects the assumptions facts
+    # with the query's facts
+    for assump in _assumptions:
+        if not expr.has(assump.expr):
+            continue
+        if _query_dict.has_key(assump.key):
+            _resolutor = get_class(_query_dict[assump.key])
+            if _resolutor.facts is not None:
+                facts.extend(_resolutor.facts )
+    if len(facts) == 0:
+        # thre are no facts and we've finished
+        return None
+
+    compiled_rules = FactRules(facts)
+
+    #phase 2, deduce it is false by fc
+    fc_query = compiled_rules.deduce_all_facts({key : True})
+    fc_query.pop(key) # we do not want to fall into infinite recursion
+
+    for k in fc_query:
+        _qresult = query(expr, k, _assumptions, qdict, nesting=False)
+        if _qresult is None:
+            continue
+        elif not (_qresult == fc_query[k]):
+            return False
+
+    # Phase 3: deduce that the query is True backward-chaining
+    for bc_query in compiled_rules.bc_ask({key : True}):
+        for k in bc_query:
+            if query(expr, k, _assumptions, qdict, nesting=False) != bc_query[k]:
+                return
+        else:
+            return True
+
+class QueryHandler(object):
+    """Base class that all Query Handlers must inherit"""
+
+    facts
...

read more »


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "documentation for the query module" by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 11:13 am
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 16:13:31 +0100
Local: Mon, Mar 16 2009 11:13 am
Subject: [PATCH 5/5] documentation for the query module
---
 doc/src/modules.txt       |    1 +
 doc/src/modules/query.txt |   85 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)
 create mode 100644 doc/src/modules/query.txt

diff --git a/doc/src/modules.txt b/doc/src/modules.txt
index 0232b4d..d13a655 100644
--- a/doc/src/modules.txt
+++ b/doc/src/modules.txt
@@ -27,6 +27,7 @@ access any SymPy module, or use this contens:
    modules/geometry.txt
    modules/galgebra/GA/GAsympy.txt
    modules/statistics.txt
+   modules/query.txt
    modules/concrete.txt
    modules/solvers.txt

diff --git a/doc/src/modules/query.txt b/doc/src/modules/query.txt
new file mode 100644
index 0000000..df9aaa1
--- /dev/null
+++ b/doc/src/modules/query.txt
@@ -0,0 +1,85 @@
+Query module
+============
+
+This module is responsible for inferring properties from objects
+
+Supported queries
+-----------------
+
+    - *bounded*
+    - *commutative*
+    - *comparable*
+    - *complex*        
+    - *composite*      
+    - *even*
+    - *finite*    
+    - *imaginary*
+    - *infinitesimal*
+    - *integer*
+    - *irrational*
+    - *rational*
+    - *nonnegative*
+    - *noninteger*
+    - *nonpositive*
+    - *nonzero*
+    - *negative*
+    - *positive*
+    - *prime*
+    - *real*
+    - *odd*
+    - *unbounded*
+    - *zero*
+
+Examples
+--------
+    >>> from sympy import Symbol, Assume, query
+    >>> query(2, 'integer')
+    True
+    >>> query(2, 'rational')
+    True
+    >>> query(1.5, 'integer')
+    Flase
+    >>> x = Symbol('x')
+    >>> query(x, 'integer', Assume(x, 'even'))
+    True
+
+You can find more examples in the in the form of test under directory sympy/query/tests/
+
+
+
+Design
+------
+Each time query is called, the appropriate Handler for the current key is called. This is
+always a subclass of sympy.query.QueryHandler. It's classmethods have the name's of the classes
+it supports. For example,
+
+For example, a (simplified) QueryHandler for the query 'positive' would look like this::
+
+    class QueryPositiveHandler(CommonHandler):
+
+        def Mul(self):
+            # return True if all argument's in self.expr.args are positive
+            ...
+
+        def Add(self):
+            for arg in self.expr.args:
+                if query(arg, self.key, self.assumptions) != True:
+                    break
+            else:
+                # if all argument's are positive
+                return True
+        ...
+
+So that the .Mul() method would be called when self.expr is an instance of Mul, the Add method
+would be called when self.expr is an instance of Add and so on.
+
+
+Extensibility
+-------------
+You can define your own queries by subclassing sympy.query.QueryHandler and passing
+to query a a qdict argument consting of the query's string and the appropriate
+handler. For example::
+
+    query(expr, 'my_query', qdict={'my_query': MyQueryHandler})
+
+would call MyQueryHandler to resolve the query 'my_query'
\ No newline at end of file
--
1.6.1.2


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "[no subject]" by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:02 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:02:16 -0700
Local: Mon, Mar 16 2009 12:02 pm
Subject: Re:
Let's push this in after the release?

I am now going to review the patches.

Ondrej


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Implement variations in sympy.utilities.iterables" by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:04 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:04:40 -0700
Local: Mon, Mar 16 2009 12:04 pm
Subject: Re: [PATCH 1/5] Implement variations in sympy.utilities.iterables

Maybe add an example:

>>> variations([1,2,3], 2, True)

[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], \
                        [3,1], [3,2], [3,3]]

> +
> +    variations(seq, n, False) will return all the variations of the list of
> +        size n without repetitions
> +    """

Maybe add an example

>>> variations([1,2,3], 2)

[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]

Otherwise +1

Ondrej


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "implement get_class and get_mod_func in sympy.utilities.source" by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:07 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:07:42 -0700
Local: Mon, Mar 16 2009 12:07 pm
Subject: Re: [PATCH 2/5] implement get_class and get_mod_func in sympy.utilities.source

Could there be tests for both of the functions above? It's not exactly
clear what they are doing from the docstrings. Also code like this is
really hackish:

getattr(__import__(mod_name, {}, {}, ['']), func_name)

If this is needed, I think it deserves a thorough docstrings and
comments why this is needed and what it does.

Ondrej


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "implement backward-chaining for propositional logic in core.facts." by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:12 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:12:37 -0700
Local: Mon, Mar 16 2009 12:12 pm
Subject: Re: [PATCH 3/5] implement backward-chaining for propositional logic in core.facts.

^^^^ I think those Assume tests should go to the next patch.

Otherwise +1.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "documentation for the query module" by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:14 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:14:09 -0700
Local: Mon, Mar 16 2009 12:14 pm
Subject: Re: [PATCH 5/5] documentation for the query module
This looks good, +1


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Implement new assumption framework." by Ondrej Certik
Ondrej Certik  
View profile  
 More options Mar 16, 12:29 pm
From: Ondrej Certik <ond...@certik.cz>
Date: Mon, 16 Mar 2009 09:29:40 -0700
Local: Mon, Mar 16 2009 12:29 pm
Subject: Re: [PATCH 4/5] Implement new assumption framework.
At first sight it looks pretty good, great job!

I want to play with this a bit more in the coming days in your branch.
Probably more docstrings could be written, if I find time, I'll write
some and send a patch.

Ondrej

...

read more »


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "implement get_class and get_mod_func in sympy.utilities.source" by Fabian Seoane
Fabian Seoane  
View profile  
 More options Mar 16, 3:22 pm
From: Fabian Seoane <fab...@fseoane.net>
Date: Mon, 16 Mar 2009 20:22:45 +0100
Local: Mon, Mar 16 2009 3:22 pm
Subject: Re: [PATCH 2/5] implement get_class and get_mod_func in sympy.utilities.source

yeah, I know it looks hackish, but it is copied from a similar utility
in the django codebase, so i'm
quite sure that there isn't a better way of doing it

It sure lacks docstrings and tests, so I'll send a reworked patch or
this and the other modules soon.

Thanks for the review,


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google