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

Idiomatic negation / set difference #805

Open
nasser opened this issue Nov 20, 2024 · 5 comments
Open

Idiomatic negation / set difference #805

nasser opened this issue Nov 20, 2024 · 5 comments
Labels
question Further information is requested

Comments

@nasser
Copy link

nasser commented Nov 20, 2024

what's the most idiomatic way to approach negation in metta? I am particularly interested it in the context of composite queries where i have a sense of how to construct a logical AND with nested matches

(friend bob larry)
(friend bob mike)

(teacher bob)
(capenter larry)
(doctor mike)

;; friend of bob AND a carpenter
! (match &self (friend bob $f) (match &self (capenter $f) $f))
;; [larry]

but it is less clear how to express negation, i.e. "friends of bob AND-NOT carpenter" which i would expect to produce [mike] given the above assertions.

relatedly I have a sense of how to model the set-theoretic intersection of two nondeterministic results

(= (intersect $a $b)
    (let* ( ($aa $a)
            ($bb $b))
        (unify ($aa $bb) ($x $x) $x (empty))))

(mammal dog)
(mammal cat)
(mammal tiger)
(bird parrot)
(bird vulture)
(pet dog)
(pet cat)
(pet parrot)

; all mammals that are pets
! (intersect (match &self (mammal $m) $m) (match &self (pet $p) $p))
;; [dog, cat]

; all birds that are pets
! (intersect (match &self (bird $m) $m) (match &self (pet $p) $p))
;; [parrot]

but it is not clear how to model set-theoretic difference, e.g. "all mammals that ARE-NOT" pets.

what's the best practice here?

@vsbogd
Copy link
Collaborator

vsbogd commented Nov 21, 2024

@nasser , thank you for the question. Simple manual way of doing it is nesting unify with alternatives. For two examples above it is:

;; friend of bob AND NOT a carpenter
! (unify &self (friend bob $f)
   (unify &self (capenter $f) ; $f is a friend of Bob
     (empty) ; $f is a carpenter
     $f) ; $f is not a carpenter
   (empty)) ; $f is a friend of Bob

;; all mammals that ARE NOT pets
! (unify &self (mammal $m)
   (unify &self (pet $m) ; $m is a mammal
     (empty) ; $m is a pet
     $m) ; $m is not a pet
   (empty)) ; $m is not a mammal

Thus in general NOT <query> can be implemented using (unify <space> <query> (empty) <if-not-result>).

@vsbogd
Copy link
Collaborator

vsbogd commented Nov 21, 2024

OR or union query can be represented using superpose:

!(superpose (
   (unify &self (mammal $m) $m (empty))
   (unify &self (bird $b) $b (empty))
))
; [tiger, cat, dog, vulture, parrot]

@vsbogd vsbogd added the question Further information is requested label Nov 21, 2024
@vsbogd
Copy link
Collaborator

vsbogd commented Nov 21, 2024

The examples I provided are AND NOT examples. To implement just NOT something instead of AND NOT something you can get the full set of results first:

!(unify &self ($p $s) (unify &self (pet $s) (empty) $s) (empty)) ; returns anything except pets

@nasser
Copy link
Author

nasser commented Nov 22, 2024

Very helpful -- thank you!

@Necr0x0Der
Copy link
Collaborator

JIC, @nasser , do you prefer pure match / unify queries or a more logical form?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants