how to use forall X in answer set programming (dlv) (answer set prolog) - answer-set-programming

I have the following facts in dlv, knows (X,Y) means X knows Y.
knows(adam, dan).
knows(adam,alice).
knows(adam,peter).
knows(adam,eva).
knows(dan, adam).
knows(dan,alice).
knows(dan,peter).
knows(eva, alice).
knows(eva,peter).
knows(alice, peter).
knows(peter, alice).
I have defined the following predicates,
person(X) :- knows(X, _).
This will give all the persons from the facts. I am trying to find a predicate popular(X). that will give the popular person. It is defined such that if all persons knows X then X is popular. The answer for the above list of facts is alice and peter. I defined it as below,
popular(X):-person(X),knows(_,X).
X is popular if its a person and everyone knows X. But I am getting all persons as the result when I run it. Where am I making a mistake?

As per the comment string on the original post, you have defined popular to be "a person that is known by someone". Since - in your knowledge base - everyone is known by someone, everyone is popular.
Assuming "a popular person is one whom everyone knows but the popular person knows only other popular persons"; if we want to know if X is popular:
We either need to count all the people that know X and then compare that to the number of people;
Or we need to verify that it is never the case that someone doesn't know X.
I'll focus on the second way to do this, using forall. Take sometime and run some tests on your own to understand how that works. Here's an example of what you might do:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
).
If you run this, you get Alice and Peter as answers.
But if we include the other condition:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
),
forall(
knows(X,Z),
popular(Z)
).
That last line says X needs to know people that are popular exclusively... and now, if you run this, you're most likely going to get a 'out of local stack' - it's a bottomless recursive definition.
You always need to check if someone is popular to know if someone is popular to know if someone is popular... Try to think about the problem and why that is. Is there a way to check if someone is popular without needing to check if someone else is popular? What if someone 'knows' themselves? What if two people know each other? This might take a slightly more complex approach to solve.
By the way, notice that your definition of person returns multiple people - everyone is a person for every person they know. Besides making every check take a lot longer (since there are more 'people' to check), this might be a problem if you decide to go with the firs approach (the counting one).
Wouldn't it make sense to define explicitly who are the people and then define 'knowing' as a relation between people?
person('Alice').
person('Bob').
knows('Alice','Bob').

As said in lurker's comment (with slight modification and emphasis by me), the reason you get all persons as a result is
You have defined person as: X is a person if X knows someone. And you've defined popular as: X is popular if X is a person and someone knows X.
But you wanted to define: X is popular if X is a person and everyone knows X.
The following is an ASP solution for clingo 4. DLV might have slight differences in syntax.
% Project
person(P) :- knows(P, _).
% Separate helper predicate knows2/2.
% Not needed if polluting knows/2 with knows(X, X) is OK.
knows2(O, P) :- knows(O, P).
knows2(P, P) :- person(P).
% Everybody knows a popular person.
% When there is a person O that doesn't know P, #false is active.
% I.e. all rule instantiations where some O doesn't know P are discarded.
popular(P) :- person(P), #false : person(O), not knows2(O, P).
% Popular person knows only other popular persons.
% Redundant at this point, since the above rule already results
% in correct answer without further integrity constraints.
:- person(P), person(O), popular(P), not popular(O), knows(P, O).
#show popular/1.

Related

Question about OCL invariants on a diagram

I'm new to OCL and currently trying to figure out how to do invariants.
I attached a picture with the diagramm I'm working on.
https://imgur.com/1ucZq5w
The invariants that I'm trying to resolve are :
a) A player has 0 or 2 cards in hand.
Context Player
inv i1: self.card->size()=0 or self.card->size()=2
b) A player, who has not played any rounds, can't have more Game Capital than the maximal Buy-In of the table.
Context Player
inv i2: self.numberOfRounds=0 implies (self.gameCapital < self.Table.maxBuyIn)
c) At every table can be only players that belong to different users
Context Player
inv i3: Player.UserAccount.allInstances().userID->isUnique()
I'm not sure if 'allInstances()' is supposed to go after Player or after PlayerAccount.
And I don't know what I'm supposed to do with the 'At every table' part of the text.
There are two more points that I really don't know how to do.
d) In the deck are 52 cards, which differ from eachother through color or value
e) The inputs of all players that still have cards in the hand are equal when bidDone True.
Can you please tell me if what I've done until now is correct and maybe some advice or solution for d) and e)?
Any help is appreciated!
Seems plausible, but I would recommend sensible names, since a validation tool will tend to report that e.g Constraint Player::i2 is not satisfied for ...
b) looks to have a < / <= bug
c) allInstances takes a type source so "Player." is wrong. allInstances is generally very inefficient to execute so should only be used as a last resort. In your case it is clearly wrong since your scope is "at every Table". You should be using context Table and then reasoning about the players at the table.
d) if you rephrase "differ from" as "is unique with respect to", you can perhaps see how you could use a Tuple of color+value as the basis for uniqueness.
e) no idea what an input is, but it just seems like a cascade of implies clauses.

Does pyDatalog have a "cut" operator like prolog?

This may be quite simple, but i can't find the answer anywhere. In Prolog, when you want to prevent it from searching for additional answers, once a variable has already been instantiated, you can use the ! sign (usually called the "cut" sign).
You can see it in this link to understand what i mean:
http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse44
for example, given the rule:
max(X,Y,Z) :- X =< Y,!, Y = Z.
if we query:
max(X,Y,X).
the ! sign will prevent prolog from backtracking and trying to prove (X =< Y) by re-instantiating X. This means that all answers will have the same value for X in them.
Is there something like this in pyDatalaog?
No, it doesn't have the cut operator. Cut is not part of Datalog, in general.
However, pyDatalog stops after finding the first value for given arguments of a function. The reference page says : "a function should be defined with the most general clause first, and more specific clauses next. When querying a function, the last one is used first, and the query stops when an answer is found."
So, you may get what you need with the following definition:
+ (max[X,Y] == Y)
(max[X,Y] == X) <= (Y < X)
Note however that there is an open issue.

What is the correct way to select real solutions?

Suppose one needs to select the real solutions after solving some equation.
Is this the correct and optimal way to do it, or is there a better one?
restart;
mu := 3.986*10^5; T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
select(x->type(x,'realcons'),[sol]);
I could not find real as type. So I used realcons. At first I did this:
select(x->not(type(x,'complex')),[sol]);
which did not work, since in Maple 5 is considered complex! So ended up with no solutions.
type(5,'complex');
(* true *)
Also I could not find an isreal() type of function. (unless I missed one)
Is there a better way to do this that one should use?
update:
To answer the comment below about 5 not supposed to be complex in maple.
restart;
type(5,complex);
true
type(5,'complex');
true
interface(version);
Standard Worksheet Interface, Maple 18.00, Windows 7, February
From help
The type(x, complex) function returns true if x is an expression of the form
a + I b, where a (if present) and b (if present) are finite and of type realcons.
Your solutions sol are all of type complex(numeric). You can select only the real ones with type,numeric, ie.
restart;
mu := 3.986*10^5: T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
20307.39319, -10153.69659 + 17586.71839 I, -10153.69659 - 17586.71839 I
select( type, [sol], numeric );
[20307.39319]
By using the multiple argument calling form of the select command we here can avoid using a custom operator as the first argument. You won't notice it for your small example, but it should be more efficient to do so. Other commands such as map perform similarly, to avoid having to make an additional function call for each individual test.
The types numeric and complex(numeric) cover real and complex integers, rationals, and floats.
The types realcons and complex(realcons) includes the previous, but also allow for an application of evalf done during the test. So Int(sin(x),x=1..3) and Pi and sqrt(2) are all of type realcons since following an application of evalf they become floats of type numeric.
The above is about types. There are also properties to consider. Types are properties, but not necessarily vice versa. There is a real property, but no real type. The is command can test for a property, and while it is often used for mixed numeric-symbolic tests under assumptions (on the symbols) it can also be used in tests like yours.
select( is, [sol], real );
[20307.39319]
It is less efficient to use is for your example. If you know that you have a collection of (possibly non-real) floats then type,numeric should be an efficient test.
And, just to muddy the waters... there is a type nonreal.
remove( type, [sol], nonreal );
[20307.39319]
The one possibility is to restrict the domain before the calculation takes place.
Here is an explanation on the Maplesoft website regarding restricting the domain:
4 Basic Computation
UPD: Basically, according to this and that, 5 is NOT considered complex in Maple, so there might be some bug/error/mistake (try checking what may be wrong there).
For instance, try putting complex without quotes.
Your way seems very logical according to this.
UPD2: According to the Maplesoft Website, all the type checks are done with type() function, so there is rather no isreal() function.

PLT Redex: parameterizing a language definition

This is a problem that's been nagging at me for some time, and I wonder if anyone here can help.
I have a PLT Redex model of a language called lambdaLVar that is more or less a garden-variety untyped lambda calculus, but extended with a store containing "lattice variables", or LVars. An LVar is a variable whose value can only increase over time, where the meaning of "increase" is given by a partially ordered set (aka a lattice) that the user of the language specifies. Therefore lambdaLVar is really a family of languages -- instantiate it with one lattice and you get one language; with a different lattice, and you get another. You can take a look at the code here; the important stuff is in lambdaLVar.rkt.
In the on-paper definition of lambdaLVar, the language definition is parameterized by that user-specified lattice. For a long time, I've wanted to do the same kind of parameterization in the Redex model, but so far, I haven't been able to figure out how. Part of the trouble is that the grammar of the language depends on how the user instantiates the lattice: elements of the lattice become terminals in the grammar. I don't know how to express a grammar in Redex that is abstract over the lattice.
In the meantime, I tried to make lambdaLVar.rkt as modular as I could. The language defined in that file is specialized to a particular lattice: natural numbers with max as the least-upper-bound (lub) operation. (Or, equivalently, natural numbers ordered by <=. It's a very boring lattice.) The only parts of the code that are specific to that lattice are the line (define lub-op max) near the top, and natural appearing in the grammar. (There's a lub metafunction that is defined in terms of the user-specified lub-op function. The latter is just a Racket function, so lub has to escape out to Racket to call lub-op.)
Barring the ability to actually specify lambdaLVar in a way that is abstract over the choice of lattice, it seems like I ought to be able to write a version of lambdaLVar with the most bare-bones of lattices -- just Bot and Top elements, where Bot <= Top -- and then use define-extended-language to add more stuff. For instance, I could define a language called lambdaLVar-nats that is specialized to the naturals lattice I described:
;; Grammar for elements of a lattice of natural numbers.
(define-extended-language lambdaLVar-nats
lambdaLVar
(StoreVal .... ;; Extend the original language
natural))
;; All we have to specify is the lub operation; leq is implicitly <=
(define-metafunction/extension lub lambdaLVar-nats
lub-nats : d d -> d
[(lub-nats d_1 d_2) ,(max (term d_1) (term d_2))])
Then, to replace the two reduction relations slow-rr and fast-rr that I had for lambdaLVar, I could define a couple of wrappers:
(define nats-slow-rr
(extend-reduction-relation slow-rr
lambdaLVar-nats))
(define nats-fast-rr
(extend-reduction-relation fast-rr
lambdaLVar-nats))
My understanding from the documentation on extend-reduction-relation is that it should reinterpret the rules in slow-rr and fast-rr, but using lambdaLVar-nats. Putting all this together, I tried running the test suite that I had with one of the new, extended reduction relations:
> (program-test-suite nats-slow-rr)
The first thing I get is a contract violation complaint: small-step-base: input (((l 3)) new) at position 1 does not match its contract. The contract line of small-step-base is just #:contract (small-step-base Config Config), where Config is a grammar nonterminal that has a new meaning if reinterpreted under lambdaLVar-nats than it did under lambdaLVar, because of the specific lattice stuff. As an experiment, I got rid of the contracts onsmall-step-base and small-step-slow.
I was then able to actually run my 19 test programs, but 10 of them fail. Perhaps unsurprisingly, all the ones that fail are programs that use natural-number-valued LVars in some way. (The rest are "pure" programs that don't interact with the store of LVars at all.) So, the tests that fail are exactly the ones that use the extended grammar.
So I kept following the rabbit hole, and it seems like Redex wants me to extend all of the existing judgment forms and metafunctions to be associated with lambdaLVar-nats rather than lambdaLVar. That makes sense, and it seems to work OK for judgment forms as far as I can tell, but with metafunctions I get into trouble: I want the new metafunction to overload the old one of the same name (because existing judgment forms are using it) and there doesn't seem to be a way to do that. If I have to rename the metafunctions, it defeats the purpose, because I'll have to write whole new judgment forms anyway. I suppose that what I want is a sort of late binding of metafunction calls!
My question in a nutshell: Is there any way in Redex to parameterize the definition of a language in the way I want, or to extend the definition of a language in a way that will do what I want? Will I end up just having to write Redex-generating macros?
Thanks for reading!
I asked the Racket users mailing list; the thread begins here. To summarize the resulting discussion: In Redex as it stands today, the answer is no, there is no way to parameterize a language definition in the way I want. However, it should be possible in a future version of Redex with a module system, which is in the works right now.
It also doesn't work to try to use Redex's existing extension forms (define-extended-language, extend-reduction-relation, and so on) in the way I tried to do here, because -- as I discovered -- the original metafunctions do not get transitively reinterpreted to use the extended languages. But a module system would apparently help with this, too, because it would allow you to package up metafunctions, judgment-forms, and reduction relations together and simultaneously extend them (see the discussion here).
So, for now, the answer is, indeed, to write a Redex-generating macro. Something like this works:
(define-syntax-rule (define-lambdaLVar-language name lub-op lattice-values ...)
(begin
;; Entire original Redex model goes here, with `natural` replaced with
;; `lattice-values ...`, and instances of `...` replaced with `(... ...)`
))
And then you can instantiate particular lattices with, e.g.,:
(define-lambdaLVar-language lambdaLVar-nat max natural)
I hope Redex does get modules soon, but in the meantime, this seems to work well.

Documenting Scala functional chains [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Scala (and functional programming, in general), advocates a style of programming where you produce functional "chains" of the form
collection.operation1(...).operation2(...)...
where the operations are various combinations of map, filter, etc.
Where the equivalent Java code might require 50 lines, the Scala code can be done in 1 or 2 lines. The functional chain can change an input collection to something completely different.
The disadvantage of the Scala code is that 10 minutes later (never mind 6 months later), I can't figure out what I was thinking, because the notation is so compact, and lacks type information (because of implied types).
How do you document this? Do you put a large block comment before the chain, changing an elegant 1 line solution into a bulky 40 line solution consisting of 39 lines of comment? Do you intersperse your comments like this?
collection.
// Select the items that meet condition X
filter(predicate_function).
// Change these items from A's to B's
map(transformation_function).
// etc.
Something else? No documentation? (Leave them guessing. They'll never "downsize" you then, because no one else can maintain the code. :-))
If you find yourself writing comments at that detail level, you're just repeating what the code says.
For long functional chains, define new functions to replace parts of the chain. Give these meaningful names. Then you might be able to avoid comments. The names of these functions themselves should explain what they do.
The best comments are the ones that explain why the code does something. Well-written code should make the "how" obvious from the code itself.
I don't write that code to begin with (unless it's a script for one-time use or playing around in the REPL).
If I can explain what the code does in one comment and the reads okay, then I keep it as a one liner:
// Find all real-valued square roots and group them in integer bins
ds.filter(_ >= 0).map(math.sqrt).groupBy(_.toInt).map(_._2)
If I can't understand this by reading carefully through the chain of commands, then I should break it up more into functionally distinct units. For example, if I expected someone to not realize that the square root of a negative number is not real-valued, I would say:
// Only non-negative numbers have a real-valued square root
val nonneg = ds.filter(_ >= 0)
// Find square roots and group them in integer bins
nonneg.map(math.sqrt).groupBy(_.toInt).map(_._2)
In particular, if someone doesn't know the Scala collections library well, and doesn't have the patience to spend five to ten minutes understanding one line of code, then either they shouldn't be working on my code (nor on anything else that accomplishes something nontrivial that they don't understand and don't have the patience to understand), or I should know in advance that I'm providing an e.g. language and mathematics tutorial in addition to writing working code, either by writing a paragraph explaining how the following line works, or breaking it out command by command, or including comments at the start of each anonymous function explaining what is going on (as appropriate).
Anyway, if you can't understand what it does, you probably need some intermediate values. They are very helpful for mental-resetting ("I can't see how to get from A to C!...but...okay, I can understand A to B. And I can understand B to C.")
If your chained operations are all monadic transforms: map, flatMap, filter, then it's often much, much clearer to rewrite the logic as a for-comprehension.
coll.filter(predicate).map(transform)
could become
for(elem <- coll if predicate) yield transform(elem)
it's even easier to show off the power of the technique if you have a longer sequence of operations, such as with Kassen's example:
def eligibleCustomers(products: Seq[Product]) = for {
product <- products
customer <- product.customers
paying <- customer if customer.isPremium
eligible <- paying if paying.age < 20
} yield eligible
If you don't want to split it in multiple methods as hammar suggested you can split the line and give the intermediate values names (and optionally types).
def eligibleCustomers: List[Customer] = {
val customers = products.flatMap(_.customers)
val paying = customers.filter(_.isPremium)
val eligible = paying.filter(_.age < 20)
eligible
}
The linelength is a somehow natural indicator, when your chain is getting too long. :)
Of course, it will depend upon how trivial the chain is:
customerdata.filter (_.age < 40).filter (_.city == "Rio").
filter (_.income > 3000).filter (_.joined < 2005)
filter (_.sex == 'f'). ...
I recently had your impression, where an application of 3 files, one of them a bit lengthy, consisting of 4 classes, one of them not trivial, and of about 10 to 20 methods. Each method was about 5 to 10 lines, and each 2 of them could have been easily combined to a lager one, but I had to convince myself, that although measuring the elegance in spared lines of codes isn't completely wrong, sparing lines isn't the goal itself.
But splitting a method into two often makes complexity per line lower, but not the overall complexity, to understand the whole program.
If the problem domain is complex - filter data at different levels, rowwise, columnwise, map it, group it, build averages, build graphs, paginate them ... - the complicated job has to be done somewhere.
The program isn't more easy to understand, you just have to hit page down less often. It is a readjustment, that you have to read a line of code more slowly.
It doesn't bother me that much now I'm used to Scala. If you want to be more explicit with types, you can always, for example, replace things like map(_.foo) with map { a:A => a.foo } to make the code more readable in lengthy/complex operations. Not that I usually find the need to do that.