Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First Order Logic #7608

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open

First Order Logic #7608

wants to merge 20 commits into from

Conversation

@sd-biswas
Copy link

@sd-biswas sd-biswas commented Jun 18, 2014

  • Make sure tests pass
  • Use Symbol everywhere, not strings (or Constant or Variable or whatever)
  • Add docstring with doctest to every class and function (including and especially abstract classes, although the abstract classes do not need to have doctests if that does not make sense). Major methods of classes should have this as well.
  • Address #7608 (comment)
  • Address #7608 (comment)
  • Use a single to_cnf and to_dnf and use dispatching to distinguish the two.
  • Change name for Functions.
  • Improve FOL_KB to handle multiple recursive clauses.
  • Implement Answer Extraction with the new ask.
  • Add description to Exceptions
  • Fix error in rst doc and add KB to it
self._func = func
self._args = tuple(args)

def _sympystr(self, *args, **kwargs):
Copy link
Member

@asmeurer asmeurer Jun 18, 2014

The second argument should be the printer, I think. You should use it to recursively print the arguments.

Copy link
Author

@sd-biswas sd-biswas Jun 18, 2014

All the printers here are purely for my personal convenience at this moment. All of the printer code will go into the respective file soon.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Jun 18, 2014

I think you'll need to override _hashable_content along with __eq__. Python 3 make also make you override __hash__, which you should just pass to the superclass using super.

>>> from sympy.logic.FOL import Predicate
>>> Knows = Predicate('Knows')
>>> Knows('John', 'Jack')
Knows(John, Jack)
Copy link
Member

@asmeurer asmeurer Jun 18, 2014

Are 'John' and 'Jack' implicitly converted to Symbol('John') and Symbol('Jack')?

Copy link
Author

@sd-biswas sd-biswas Jun 18, 2014

No. The are intended to be constants.

Copy link
Member

@asmeurer asmeurer Jul 16, 2014

The problem is that SymPy objects don't really play with with non-SymPy objects such as strings as part of their expression tree. In this case, I would just only use Symbol everywhere, since that is the standard way to have a 'name' in SymPy.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Jun 18, 2014

I think it would be cleaner to just use symbols in place of strings. Most actual usage will be with symbols, I think. It's just a matter of using symbols in the doctests.

self._name = name

def __call__(self, *args):
return self.apply()(self, *args)
Copy link
Member

@asmeurer asmeurer Jul 16, 2014

There should be some apply on this class, even if it just raises NotImplementedError.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Jul 16, 2014

The class structure here is still a little confusing to me. Can you add a docstring to each class that just explains what it is for, especially the abstract base classes. It also should be made clear for each class if it is designed to be used on its own or if it is only a designed to be subclassed.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Jul 22, 2014

I don't think it's a good idea to have multiple to_cnf functions. I would just have the one function, and use dispatching to have it do the right thing on different kinds of objects (i.e., have to_cnf call _eval_to_cnf on the object if it has that method, and then implement that on the logic and first order logic classes).

return expr.func(*args)


def standardize(expr):
Copy link
Member

@asmeurer asmeurer Jul 22, 2014

You should probably add a keyword argument to pass in a custom iterator of symbols.

Copy link
Member

@asmeurer asmeurer Aug 8, 2014

Similar to the symbols argument to cse().

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Aug 8, 2014

I am going to put a checklist at the top of the pull request, so that we can keep track of what needs to be done.

raise ValueError("Use a constant instead of %s()" % func)
args = [arg if isinstance(arg, (Boolean, Symbol))
else Constant(arg) for arg in args]
self._func = func
Copy link
Member

@asmeurer asmeurer Aug 8, 2014

Is this at all related to self.func (which will be the class, Applied)?

Copy link
Member

@asmeurer asmeurer Aug 18, 2014

The issue with using a property is that it leads to confusion to people reading the code from here, as you can see from this comment of mine.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Aug 12, 2014

I was hoping for more than just "abstract base class" in the docstrings of the abstract base classes. For someone coming to this module for the first time, it can be quite unclear what all the abstract classes are supposed to represent. It would be helpful to give a higher level idea of why they are there.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Aug 12, 2014

I think the Python 3 test failures are coming from using strings instead of SymPy objects in the doctests.

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Aug 12, 2014

  1. I'll work on better documentation.
  2. Simply calling to_snf followed by to_cnf/to_dnf (in boolalg) should give the user the required CNF/ DNF. to_snf returns an expression with no quantifiers (existentially bound variables are replaced by skolem functions and all other variables are considered to be universally quantified). Following this, any boolalg function can be called on this expression. The major requirement for CNF is for resolution, and the resolution method takes care of all this.
  3. I will fix it in some time.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Aug 12, 2014

Simply calling to_snf followed by to_cnf/to_dnf (in boolalg) should give the user the required CNF/ DNF. to_snf returns an expression with no quantifiers (existentially bound variables are replaced by skolem functions and all other variables are considered to be universally quantified). Following this, any boolalg function can be called on this expression. The major requirement for CNF is for resolution, and the resolution method takes care of all this.

Good. I like this better. CNF and DNF should be only about propositional logic, and should treat quantifiers basic terms.

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Sep 9, 2014

  1. Oh, that should fix the problem then. The Predicate in FOL represents the most generic predicate possible. So subclassing other things from it makes sense. If the name of Predicate (in assumptions) is changed to AssumptionsPredicate I'll have to make changes throughout assumptions to reflect the same. A quick grep shows that currently assumptions, core/tests and solvers/inequalities use this name. Do you know of anything that needs to be changed?
  2. I think we should not make boolalg (BooleanFunction) dependent on FOL, simply from the perspective of logical separation. As far as possible we should keep the code for FOL limited to its file.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Sep 9, 2014

  1. It shouldn't be used in many places. Also, if someone has code that uses Predicate and they don't update it to use AssumptionsPredicate the worst that will happen is that it won't print with the Q any more, right?
  2. But is BooleanUndefinedFunction useful outside of FOL?

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Sep 9, 2014

  1. The AssumptionsPredicate has these extra methods: add_handler, remove_handler, sort_key, eval.
  2. BooleanUndefinedFunction has no use outside FOL

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Sep 9, 2014

add_handler and remove_handler are assumptions specific. The sort_key should stay on the Predicate object. I don't know what eval is, but it sounds like something that should stay on Predicate as well.

Remind me again what a BooleanUndefinedFunction represents. It's just a function f(X) except unlike Function('f') from the core, it is assumed to take on boolean values, right?

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Sep 13, 2014

@SDB1323 will you be able to finish this in the next week? Otherwise, it will need to be pushed to the next release.

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Sep 13, 2014

Yes, it should be ready by the next weekend.

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Sep 19, 2014

@asmeurer Please have a look at sd-biswas#1. Please confirm that this is what you want to be done finally. Additionally I need a little help from you because something is screwing up in ask once I do this.

@asmeurer
Copy link
Member

@asmeurer asmeurer commented Sep 21, 2014

I'm removing the milestone. If you finish this, please let me know and we can still get it in, but I don't want to block the release on it.

@asmeurer asmeurer removed this from the 0.7.6 milestone Sep 21, 2014
@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Sep 21, 2014

Okay, sure. I am on this at the moment. I have modified the FOL classes to mimic the original Assumption classes. But that is creating errors in my code, so fixing that at the moment.

@peterwittek
Copy link

@peterwittek peterwittek commented Jan 26, 2017

Is there any progress with this? Thanks.

@ghost
Copy link

@ghost ghost commented Jan 19, 2018

I'm also interested in this, it appears to be halted now. Is there currently any plans for first-order logic in the future?

@sd-biswas
Copy link
Author

@sd-biswas sd-biswas commented Jan 19, 2018

@naiveaiguy Please speak to the maintainers. I have been away for a very long time and don't know the current state of things here. If there is still interest in having FOL then I can help you with modifying and/or rewriting this code.

skirpichev added a commit to skirpichev/diofant that referenced this issue Oct 29, 2018
Mechanistic port of sympy/sympy#7608 for Diofant
by @skirpichev.
skirpichev added a commit to skirpichev/diofant that referenced this issue Oct 29, 2018
Mechanistic port of sympy/sympy#7608 for Diofant
by @skirpichev.
skirpichev added a commit to skirpichev/diofant that referenced this issue Jan 13, 2019
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Jan 13, 2019
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Feb 28, 2019
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Aug 7, 2019
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Oct 8, 2019
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Jan 28, 2020
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
skirpichev added a commit to skirpichev/diofant that referenced this issue Jan 29, 2020
Mechanistic port of sympy/sympy#7608 for Diofant

// edited by @skirpichev

100% test coverage.
@czgdp1807
Copy link
Member

@czgdp1807 czgdp1807 commented Apr 24, 2020

This should be there in SymPy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

7 participants