2

I understand that Prolog is not an object-oriented language, and after reading a few StackOverflow posts, it is not clear to me that this is feasible, but I figured I'd ask anyway:

If a Customer has and only has a name (atomic string) and an age (integer), is it possible to ask Prolog to give some examples of Customer dictionaries, given a list of possible names and an age range? Actual usage will feature extensive constraints on dictionary values.

For example, ideally I want something like this

between(18, 60, Customer.age),
member(Customer.name, [jodie, tengyu, adiche, tomoyo, wolfgang]),
Customer = whatisthis{age: What, name: Wot}.

to give me something like

Customer = whatisthis{age: 24, name: tomoyo} ;
Customer = whatisthis{age: 55, name: tengyu} ;
...
...
Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Zhanwen Chen
  • 1,295
  • 17
  • 21
  • Ordinarily, one would just populate the database with `customer(tomoyo, 24). customer(tengyu, 55).` and then query it with `customer(Name, Age).`. SWI does have [dictionaries](http://www.swi-prolog.org/pldoc/man?section=dicts), and there is always [Logtalk](https://logtalk.org/) if you need object-oriented Prolog. – Daniel Lyons May 21 '19 at 15:24
  • @DanielLyons The problem is that I don't have finite ground truths like a database. In other words, these `Customer`s don't actually exist, so `customer(tomoyo, 24)` wouldn't logically be a ground truth. Instead I'm generating all possible `Customer`s. – Zhanwen Chen May 21 '19 at 15:30
  • 3
    `customer(Name, Age) :- member(Name, [jodie, tengyu, adiche...]), between(18, 60, Age).` Not random, but gives you a bunch of stuff. – Daniel Lyons May 21 '19 at 15:47
  • @DanielLyons Thanks. Another practical constraint of my problem is that my argument list can be extremely long, so using positional argument matching may limit readability and extensibility. – Zhanwen Chen May 21 '19 at 15:55
  • This sounds like test case generation. Is that correct? – Guy Coder May 21 '19 at 18:27
  • @GuyCoder That sounds similar. Really I'm using it to generate legal convolutional neural networks given a bunch of layer size constraints. – Zhanwen Chen May 21 '19 at 18:29
  • I know what a `convolutional neural network` is, but don't know what a `legal convolutional neural network` is but I am thinking it is just legal data for a `convolutional neural network` but the phrase `generate legal convolutional neural networks` has me scratching my head on what it means. If the work `train` instead of `generate` were used that would make sense. – Guy Coder May 21 '19 at 18:39
  • @GuyCoder By legal I mean layer sizes >= 1. Because each layer depends on the previous layer, if you have a convolutional kernel size that's too big (say in the first layer), you might end up having a negative output size several layers down and that's bad. A better term for what I'm doing is Neural Architecture Search. – Zhanwen Chen May 21 '19 at 18:42
  • 1
    So basically setting aside the use case for the neural network, you want to generate lots of data but within given constraints and are interested if Prolog can do that. The answer is yes, the way in which to use Prolog to do it is the real question. Use a custom written generator like Daniel noted, make use of Prolog unit test [forall](https://stackoverflow.com/q/54334567/1243762) , use [constraints](http://www.swi-prolog.org/man/clpfd.html]) and/or [Markov chains](https://www.metalevel.at/misc/markov.pl) are just the ones I can think up off the top of my head. – Guy Coder May 21 '19 at 19:29
  • 1
    [Constraints](http://www.swi-prolog.org/man/clpfd.html) Sorry for bad link in earlier comment. Can't change comments after 5 minutes. – Guy Coder May 21 '19 at 19:57

1 Answers1

4

In SWI-Prolog, you actually do have dicts. Here:

?- between(2,3,X), Age is 20*X, member(Name, [tomoyo, tengyu]), Dict = customer{name:Name,
age:Age}.
X = 2,
Age = 40,
Name = tomoyo,
Dict = customer{age:40, name:tomoyo} ;
X = 2,
Age = 40,
Name = tengyu,
Dict = customer{age:40, name:tengyu} ;
X = 3,
Age = 60,
Name = tomoyo,
Dict = customer{age:60, name:tomoyo} ;
X = 3,
Age = 60,
Name = tengyu,
Dict = customer{age:60, name:tengyu}.

You can add and remove key-value pairs from dicts at run-time. The only limitation is that the keys must be atomic terms.

The documentation is here:

http://www.swi-prolog.org/pldoc/man?section=bidicts

User9213
  • 1,316
  • 6
  • 12