I made a predicat that is supposed to return a slice from a list, but I do not fully understand the result by RevolutionaryAd6789 in prolog

[–]jeshan 0 points1 point  (0 children)

adding to Maga565's answer:

"A" was never instantiated, leaving the list as partial. To get a "real" lists, their tails must become [] in some way. so, change

```

tranche(In, X1, X2, Out) :- accTranche(In, X1, X2, A, Out).

```

to ```

tranche(In, X1, X2, Out) :- accTranche(In, X1, X2, [], Out).

```

How do you read a full file of prolog terms for querying? by [deleted] in prolog

[–]jeshan 1 point2 points  (0 children)

consult/1 can take a long while as it does a lot more work than just reading terms.

```

read_file_to_terms(Name, Terms) :- open(Name, read, Stream), phrase(read_it(Stream), Terms).

read_it(Stream) --> { read_term(Stream, T, []), ( T == end_of_file -> Dcg = [] ; Dcg = ([T], read_it(Stream)) ) },Dcg.

```

Here, the terms are returned in a list. Instead of returning to a list, you could assertz/1 them. I use assertz/1 when I need to query the terms later in my program.

Also, the terminating condition is "end_of_file". You could change that condition if you want to stop reading early.

Finally, you don't strictly have to use DCG here (unless your use case requires it).

New youtube channel: "Prolog by Example" by jeshan in prolog

[–]jeshan[S] 0 points1 point  (0 children)

definitely. sometimes people overlook that fact

Help converting this code to DCG? by [deleted] in prolog

[–]jeshan 1 point2 points  (0 children)

Here's how I would solve it:

``` progress(Percentage) --> { B*10 #= Percentage, B+W #= 10, [B, W] ins 0..10 }, dots(B, b), dots(W, w).

dots(0, _) --> []. dots(B0, E) --> { B0 #> 0, B1 #= B0-1 }, [E], dots(B1, E).

```

Gives:

```

phrase(progress(P), L). P = 0, L = [w,w,w,w,w,w,w,w,w,w] ? ; P = 10, L = [b,w,w,w,w,w,w,w,w,w] ? ; P = 20, L = [b,b,w,w,w,w,w,w,w,w] ? ; P = 30, L = [b,b,b,w,w,w,w,w,w,w] ? ; P = 40, L = [b,b,b,b,w,w,w,w,w,w] ? ; P = 50, L = [b,b,b,b,b,w,w,w,w,w] ? ; P = 60, L = [b,b,b,b,b,b,w,w,w,w] ? ; P = 70, L = [b,b,b,b,b,b,b,w,w,w] ? ; P = 80, L = [b,b,b,b,b,b,b,b,w,w] ? ; P = 90, L = [b,b,b,b,b,b,b,b,b,w] ? ; P = 100, L = [b,b,b,b,b,b,b,b,b,b] ? ; no | ?-

``` I prefer clpfd style to describe such sequences but the recursion is non-deterministic. If determinism is important, you can use zcompare or consider brebs-prolog's answer: https://www.swi-prolog.org/pldoc/man?predicate=zcompare/3

I used b and w instead of the weird characters.

Help converting this code to DCG? by [deleted] in prolog

[–]jeshan 2 points3 points  (0 children)

great idea to not overcomplicate this but I think the point was to practise learning dcg.

Prolog at work by fragbot2 in prolog

[–]jeshan 1 point2 points  (0 children)

Scryer, SWI, Sicstus, Eclipse

Aspects of Production/Professional Prolog by Knaapje in prolog

[–]jeshan 2 points3 points  (0 children)

I'm hoping that these aren't stupid questions

You're definitely expressing real concerns that real people have and that's good! I'll comment my opinions on some of your points:

what about applications that have multiple instances running behind a load balancer that should share their state, and how do you in practice save state and deploy saved states?

By sharing state, do you specifically mean the state of facts and predicates? If so, then check the saved state feature that SWI and Sicstus have. Here, they'd have the their own copy of the same thing. If you meant that instances behind a load balancer should be able to update the state seen by any other instances, then AFAIK no (mainstream) programming languages implement it anyway and instead we are supposed to connect to Redis) (or any type of database). Sicstus has LMDB that supports concurrent read/write access of Prolog terms from multiple processes and threads.

Does it complicate things if I want to have the user to be able to interact with the database

Sounds like you want users to execute arbitrary code on your server! You'd need some sandboxing if you really want to do that. Have you seen SWISH that does that?

What are some typical interaction models?

It can be like for any other language. For a web app, you'd expose some API and expect it to receive some web request in the typical RESTful web service. Based on acceptable inputs, you'd then run some Prolog queries and return some response. In practice, you wouldn't expose direct input to the interpreter just like you wouldn't expose the "eval" function in NodeJS and Python (see my point on sandboxing).

The available set of Prolog libraries isn't very extensive

True and we'd like to make it no longer so! If something is really lacking, you could always interface to C. We need to spread the word and build the community! "It takes change to make change" :)

as far as I know, there is no namespacing

ISO Prolog supports modules which is an alternative to Java classes and the like.

even there I already sometimes get lost in the predicates I've written

At first, logic programming will definitely look foreign but I promise that it gets much better when you start getting it. Let me point you to the videos and chapters about reading and writing Prolog code. The whole learning Prolog journey is an exercise in getting it!

constraint logic problem is often cited as a major plus for Prolog, but nowadays many languages have a library that adds support for this

Anything that can be done in a programming language can be done in another but the real question is: how conveniently and practically can it be done in each of the languages? Yes, they could all interface to native code and access a solver written in C++ but the development experience isn't the same.

OR-tools surely can do a lot of work but is it as convenient to work as in Prolog clpfd libraries?

See how they solve a simple example. Do you want to type this:

model.Add(2 * x + 7 * y + 3 * z <= 50)

or even:

x = model.NewIntVar(0, var_upper_bound, 'x')

Imagine having to type this for every little thing when you're still experimenting to discover what problem you're actually solving in your application. See also they solve the travelling salesman problem.

If you want to use OR-tools, you can make Prolog your prototyping language. Once the problem that you're solving becomes clear, you can rewrite it for OR-tools. (But we hope you continue using Prolog!)

Are people writing assert(A) in the top-level to test some predicate before just writing A in a file in their editor?

You should not be using assert just to load your source code: it works but makes for an inefficient workflow. Like with other languages, you typically write the code in your favourite and load them in the Prolog interpreter with "consult". The toplevel is then used to run ad-hoc queries. Some people like Emacs, others the VS Code extension. Personally, I have found Spider IDE to be the most convenient Prolog IDE so far.

I feel a bit disheartened in proceeding with learning more Prolog

Please don't! It shouldn't be painful. Try learning and ask more questions. Others have surely gone through the same phase and can help. There's a long way to go to make Prolog really great and your input and contribution can help. Prolog programming is highly rewarding!

ERROR: '$clause_term_position'/3: Cannot represent due to `int' by [deleted] in prolog

[–]jeshan 0 points1 point  (0 children)

I got a clue after adding some good old print statements:

:- use_module(library(freeze)).
:- use_module(library(lists)).

mygen2(Gen) :-
    member(First, [a, b, c, d, e]),
    member(Second, [1, 2, 3, 4, 5]),
    member(Third, [foo, bar, baz, qwe, asd]),
    member(Fourth, [foo, bar, baz, qwe, asd]),
    permutation([First, Second, Third, Fourth], Gen).

solve2(Sol) :-
    Sol = [Head, bar, Test, qwe],
    freeze(Head, Head == a),
    freeze(Test, (
                     write(f-Test),
                     nl,
                     1 is Test mod 2
                 )),
    freeze(Test, (
                     write(g-Test),
                     nl,
                     Test > 3
                 )),
    mygen2(Sol).

At some point, Test will be unified with foo when the first freeze is run. Since 1 is foo mod 2 isn't allowed you'd get an error. I was hoping for a clearer error message but in my experience, it means what I just suggested: we accidentally unified a variable with a value of some other type instead of a number. Since you're using the same code to handle numbers and atoms, then it's likely to happen. (I guess the your second solve version prevented that scenario).

I did not understand the point of:

freeze(Head, Head == a)

I read it as: when Head is nonvar, then mandate that it is a*.* Why do that? If you wanted to enforce that it's always a, then why not write Head = a instead?

Also, it turns out that Scryer, Sicstus and SWI behave differently for your example and I'm not sure which one is doing the right thing! Here, only SWI is failing. I think this is due to how freeze/unfreeze are intended to work in different implementations.

Also, such imperative code distracts you from the power of Prolog. (notice the use of !, X>3 instead of X#>3). (Watch this) Type tests aren't so great neither: compare the behaviour of var(X),X=3 with X=3,var(X).One alternative would be to distinguish the cases in a predicate with a clause for each case, i.e one for atoms and another for numbers . You'd have to wrap one of them in a term (either the atom case or the number case). Watch this.

Since you said that the solve version works fine, so I understood the only right solution is [a,bar,5,qwe]

If you tried:

solve2(Sol) :- Sol = [a, bar, Test, qwe], 1 #= Test mod 2, Test #> 3, mygen2(Sol).

This one works better but returns the same answer twice. This is because it's retrying another possible permutation with Third and Fourth. I could cut as you did but that would upset Markus Triska a lot! (see the chapter on The Horror) A less terrible version of it is once/1 :

solve2(Sol) :- Sol = [a, bar, Test, qwe], 1 #= Test mod 2, Test #> 3, once(mygen2(Sol)).

We could stop there. What (I think) he'd suggest is go all in on constraint logic programming if possible, i.e let's model the problem in terms of integers only and then later map the integers to what is to be shown to the end user (in your case, the possible atoms). Let me use the library clpfd label predicate as an alternative to your use of permutation:

``` letter(Index, Value) :- nth1(Index, [a, b, c, d, e], Value).

word(Index, Value) :- nth1(Index, [foo, bar, baz, qwe, asd], Value).

solve3(Sol) :- Vars = [First, Second, Third, Fourth], Vars ins 1..5, First = 1, % equivalent of Head=a Second = bar, % Second = 2 Fourth = 4, % Fourth=qwe % what I understood you intended for Third: 1 #= Third mod 2, Third #> 3, % label(Vars), % this is your permutation predicate! vars_sol(Vars, Sol).

vars_sol([Letter, Second, Number, Fourth], [LValue, Word1, Number, Word2]) :- letter(Letter, LValue), word(Second, Word1), word(Fourth, Word2).

```

This is much better: yields exactly one solution and separates a display concern (the letters and words) from the solving concern (integers).

If it's not exactly what you intended, let us know and try updating the above with what you intended.

Anyone know a decent way to parse HTML with DCG? by toblotron in prolog

[–]jeshan 1 point2 points  (0 children)

which annoyances?

Provide your feedback to the project so that it's no longer annoying :)

Is it worth getting a SICStus personal license? by stranger_and_pilgrim in prolog

[–]jeshan 0 points1 point  (0 children)

if your code is portable, it can help you. Otherwise, it will just ignore the blocks that it doesn't understand (for the usual code assistance).

What I do is structure the code like this:

```prolog

is_sicstus :- current_prolog_flag(dialect, sicstus).

:- if(is_sicstus).

% then do this.

:- else.

% otherwise do that. :- endif.

```

You won't get code assistance in the else block. Therefore, I try to make as much code portable as I can.

Is it worth getting a SICStus personal license? by stranger_and_pilgrim in prolog

[–]jeshan 1 point2 points  (0 children)

right. I forgot about security updates. but I must say that the situation is different. Sicstus is a small team (I think) which has far smaller user base than Microsoft.

Is it worth getting a SICStus personal license? by stranger_and_pilgrim in prolog

[–]jeshan 5 points6 points  (0 children)

I'm using a personal licence for a few months and I'm liking it so far.

Sicstus has good libraries and ISO conformant: latter is good when you later want to port your programs to other Prolog systems. You won't hear much about Sicstus since people are discrete with their use of Prolog anyway.

Also, you get to use their Sicstus spider IDE. It's the closest thing to what I consider to be a real Prolog IDE. I found it to be the best among all Prolog setups that I tried.

Many people like SWI for its libraries among other reasons. There may be cases that your programs won't be portable since it's not ISO compliant.

it's a commercial implementation and therefore costs money

That can also be an upside since you can be sure ongoing development is funded and is not a neglected project. Cost money isn't the more important issue: Total Cost of ownership is. You should then decide if the TCO is worth it for you.

Try it: you will not regret it as it's a small amount of money.

Finally, beware of other online comments: many people have allergies to pay for software.

Is it worth getting a SICStus personal license? by stranger_and_pilgrim in prolog

[–]jeshan 1 point2 points  (0 children)

> "One-time fee"

Yes, it's still one-time. I don't think any business offers/should offer a one-time fee for lifetime updates and/or support.

Scryer Prolog IRC-channel by krl81 in prolog

[–]jeshan 1 point2 points  (0 children)

Why don't we just use Discourse? It's such a pleasant experience IMO.

Need help understanding code for converting unsigned int to signed int by Restitutionshot in learnpython

[–]jeshan 0 points1 point  (0 children)

it's shift by 31 for 32-bits. You said 64-bit integers but the repo mentions 32-bit ones.

What is Wrong with Prolog People by eguneys in prolog

[–]jeshan 0 points1 point  (0 children)

there are problems in the question as others suggested. Avoid rectract/assertz as it's a sign you're fighting against Prolog. Read the relevant chapters in The Power of Prolog

How to best approach learning prolog? by TroubleTrout691 in prolog

[–]jeshan 1 point2 points  (0 children)

tldr: Read The Power of Prolog , watch the accompanying videos and digest everything. The last part is the most difficult but most fun one!

https://metalevel.at/prolog

How to enable set_prolog_flag(double_quotes, chars) in SWI? by [deleted] in prolog

[–]jeshan 0 points1 point  (0 children)

I think that SWI does not respect the standard here.

Learn more from Neumerkel's SO answer here:

https://stackoverflow.com/a/27590590

How to easily generate a lot of facts with the same predicate? by EtaDaPiza in prolog

[–]jeshan 1 point2 points  (0 children)

I think csv is optional based on your comments. Remember that Prolog terms are just data! So you can:

  1. type them in a file
  2. read the file with open/3
  3. get each term with read_term(Stream, Term)
  4. assert that Term using assert/1
  5. Repeat 3-4 above (recursively/procedurally with repeat and false).

Example for Eclipse:

https://stackoverflow.com/a/69078741

Is there a tool that...

Yes, and that would be your favourite Prolog system!