How Prolog Performs Repeated Processing

Asked 4 months ago, Updated 4 months ago, 9 views

Below is a program that writes data given in table (or matrix) format in csv file format.

The reason why I use append/3 here is to avoid fail driving, but it feels a little unnatural.
How can I improve the code to make it easier to understand?

put_csv_lines(_csv file,_separator, LL):-  
tell(_csv file),  
Display one line at a time (LL),  
Told.  

Display line by line (LL):-  
append(_, [L|R], LL),  
concat_atom (L, _ delimiter, _ line display),  
writef('%t\n', [_line display],  
R = [ ].  

The main reason why append/3 is used here is when all lines are finished with the last sub-target R=[] Because I want to end the predicate with the truth.If there is no problem, member/2 should be fine.

Display one line at a time (Outstream, LL):-  
member(L,LL),  
concat_atom (L, _ delimiter, _ line display),  
writef(_line feed, '%t\n', [_line display],  
write (Outstream,_line display with new line),  
fail.  
display one line at a time  

The one who disliked this style is the definition using append/3 above.Now, what else? Is there an alternative expression?

prolog

2022-09-30 11:09

2 Answers

I will comment as a questioner.
Why don't we use forall/2?I was looking forward to hearing that
You answered as expected.

I wrote it as a comment to the respondents above, but it's hard to read, so I'll rewrite it.
Code called failed drive

foo(L):-  
  member(A,L),
  writef('%t\n', [A]),
  fail.
foo(_).

Use this for all/2 and

foo(L):-  
  forall(member(A,L),writef('%t\n',[A]))  

It's a refreshing rewrite.
For all (P, Q) is true in all cases where P becomes true, so is Q.That's what it means.
If P is true and Q is false, forall/2 itself fails.
Forall/2 has the above relationship between P and Q.Alternatively, it is a predicate for examining relationships
It can also be said that
However, in the above example, the predicate defining the relationship is used to express procedural conjunctions. Yes.
I like to use this expression because I think it's OK, but I have something to keep in mind.That's
In the Q-side section, there should be no cases where the code above does not reach the fail.
This is only writef/2 here, so it is obvious that this will be true and fail, but
If the code in Q is large, complicated, or contains Exception,
I suspect that there may be cases where the failure has not been reached, so I need to crush it. Yes.


2022-09-30 11:09

You can combine forall/2 and member/2 for repeat processing.

 save_as_csv_file (File, Separator, Table):-
    open(File, write, Out),
    for all (member(Row, Table),
           write_csv_line (Out, Separator, Row),
    close(Out),
    !.

write_csv_line(Out, Separator, Row):-
    concat_atom(Row, Separator, Line),
    writef (LineNL, '%t\n', [Line],
    write (Out, LineNL)

This way of writing can honestly express the processing of write_csv_line for each member of the table Row.

Of course, people who read this cannot understand unless they know how to use forall/2.However, a failure-driven loop is not easy to read from the program how far it will backtrack after a failure, putting a strain on the program reader.


2022-09-30 11:09

If you have any answers or tips


© 2023 OneMinuteCode. All rights reserved.