Hacker News new | past | comments | ask | show | jobs | submit login

I was confused by this example:

    rel p(s, x)
     if(s = ‘a’) //this is sugar for [(s=’a’ and x=0) or x=2]
      x = 0
     else
      x = 2
Why does it transform to

     [(s=’a’ and x=0) or x=2]
and not

     [(s=’a’ and x=0) or (s!=’a’ and x=2)]
(or whatever "not equals" is in Cosmos)?

In any language I know, "else" means "do this when the guard was _not_ true", and not "nondeterministically maybe do this other thing instead, if you want". Did I simply misunderstand it? (note that I got lost at the "soft cut" part, but did I get it right that "choose ... else" is closer to what I'd expect "if .. else" to do?)

Given that accessibility to people used to imperative languages is a core goal, I'm not sure that the choice of making "else" mean "yeah whatever" is the best one. Maybe it's better to replace it by a different keyword entirely ("if.. or.." maybe). On a related note, just in case you're not familiar with it, I believe that maybe the "if.. fi" construct in Dijkstra's Guarded Command Language[0] is an easy way to get imperative-thinking people to embrace nondeterminism. It feels a lot like normal imperative "if", except there is no "else". If you want "else", you need to add another guard explicitly, with the negation of your first guard. This way, it's easy for people to grasp that the order of the guarded commands have no meaning. It also makes introducing nondeterminism very explicit.

[0] http://en.wikipedia.org/wiki/Guarded_Command_Language#Select...




You're thinking imperatively. It is not "do this" but "generate the set of possible solutions".

The "soft cut" part I'm presuming is similar to Prolog, where a "cut" indicates that once you've gotten past it, you can't backtrack (roughly - my knowledge of Prolog is rather limited) to try other arms - so "choose" is forced down one path by the guard, and then not allowed to also evaluate the other arm, while "if" can generate both alternatives.


I am somewhat familiar with declarative programming and Prolog and still don't get it.

The problem is there even without else.

    if (s='a')
        x=2
Should it be

    (s='a') and (x=2)
or

    ((s='a') and (x=2)) or (s!='a')
Because IMHO it should be the second one (it's also basicaly the logical definition of implication, which IMHO should be consistent with "if").

The first interpretation of if without else just give you another way of writing:

    s='a'
    x=2
so why "if" at all?

And if we take the second interpretation of if without else, then when there's else - it should also get the !if_condition implicitly.


"if" here isn't a perfect analog to a traditional imperative language's if statement.

A better set of keywords to describe the logic might be "when ... allow". Because there is an implication here, it's just in reverse.

Because the relation finds all possible solutions that meet the relationship, this code really reads "when s is the letter a, allow x to be 0, and call that a solution. Otherwise, any pairing where x is 2 is a solution."

So if you were to call p(s, 0), you would find that you only get one solution, where s must be 'a'. From an imperative-ish POV, that "sets" (constrains) s to 'a'.

OP is using if, combined with the notions that you take only the first of all relation solutions, and that you treat the rightmost relation member as an output, to achieve an imperative-like behavior in a non-deterministic logic language. Which is mentioned in the paragraph following the example.


Because then what if:

    rel q(y)
     y = true
     y = false
    
    rel p(s, x)
     if(s = ‘a’)
      x = 0
     else
      x = 2
    
    rel main()
     k = q()
     if(k)
      s = 'a'
     else
      s != 'a'
     p(s,x)
     println(x)
Actually, I'd like to know what Cosmos would resolve this to as things stand. Is it just going to decide that | x = 0, | x = 2? Also can I throw probabilities into this code?


One property of Cosmos is that there is no boolean type and relations are themselves booleans (q() would be false in this case). Hence, the code would be rather like this:

  rel q()
   true
   false
  ...
  rel main()
   if(q())
    ...
Indeed, having an 'else' that negates the condition would get tough for complicated conditions. Negation-by-failure and soft-cut ('choose') have their own problems in certain circumstances.

Yeah, it's going to decide that | x = 0 | x = 2 (there is no CLP for strings).


I'm not sure either. But it could be a ruby style and, and a mix between assign and equal operator.

Then

  (s='a' and x=0)
would mean: if s=='a' then set x to 0, but if s != 'a' he would never jump to x=0, since and does stop when the result before is falsy - it is following the logical and behaviour.

The or would prevent the x=2 to be executed when the prior block is true, one true is enough.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: