clorm icon indicating copy to clipboard operation
clorm copied to clipboard

Refining/constraining predicates based on combination of fields

Open AbdallahS opened this issue 8 months ago • 5 comments

Is there a mechanism to impose constraints on the predicate sub-class based on combinations of fields?

In the following example, I would like any predicate intance that unifies with the Data class to be such that if the info type is "height" then the value is of type int and if the info type is "firstname" then the value is of type str. I would like the user3 facts not to unify with Data. A suitable solution to my problem would let me avoid the additional filtering condition in function print_data because the querying mechanism should have already filtered out the bad data.

infotype(height;firstname).
person(user1;user2;user3;user4).

data(user1,height,170).
data(user1,firstname,"Anna").
data(user2,height,180).
data(user2,firstname,"Robert").
data(user3,height,"Charlie").
data(user3,firstname,175).
data(user4,firstname,"Richard").

missing(USER,INFO) :- person(USER), infotype(INFO), not data(USER,INFO,_).

#show missing/2.

#script(python)

import clorm
import typing
from clorm.clingo import Control

InfotypeField = clorm.refine_field(clorm.ConstantField,["height","firstname"])

class Data(clorm.Predicate):
   user: clorm.ConstantStr
   type: clorm.ConstantStr = clorm.field(InfotypeField)
   value: typing.Union[int,str]

def print_data(model):
    query=model.facts(atoms=True).query(Data)
    for d in query.all():
        if (d.type == "height" and type(d.value) == int)\
        or (d.type == "firstname" and type(d.value) == str):
            print(d)
def main(ctrl_):
    ctrl = Control(control_=ctrl_, unifier=[Data])
    ctrl.ground([("base",[])])
    ctrl.solve(on_model=print_data)

#end.

I know that I could turn data to an arity-2 predicate and turn height and firstname into arity-1 function symbols. For example data(user1,height(170)). data(user1,firstname("Anna")). This would let me define a suitably constrained Data class directly, but it is undesirable for other reasons (e.g., it messes up the missing/2 rule).

AbdallahS avatar Jun 16 '24 02:06 AbdallahS