[Logo]
Forums Register Login
Inserting in a map line by line
Good morning!

I have a file that I want to put into a map line by line. I know how to put it char by char, but how can I put it line by line as far as there is no symbol for it? (or maybe "\n" but it's not visible).

here is my file:



and here is my map




Thank you in advance for your help!
(1 like)
Use a BufferedReader, which you can get from Files.newBufferedReader(). This gives you access to the readLine method.
(1 like)
Don't use the read() methods, unless you need to be convinced how bad they are.
I worked with a simple array but used a bufferReader, I think its use is quite similar for a map.
Thank you for the idea!


In Java 8 you can also use Files.lines method.
I think I have an issue however, when reading the file and giving each lines to Clauses.
Indeed having used a buffer, I do Clause = readLine(); (yet, I think it's unable to change lines by itself.)

with the following file projet.pl



And the following code



And on the terminal I have:



So I think I don't use quite well the readLine command...
(1 like)
Use printStackTrace() when printing out exception details.
That will give you the stack trace as well as the error message, so you know exactly where in your code the exception occurred.

You call readLine() twice, by the way, which may be the cause of your problem.
Shouldn't the assignment to Clauses[i] use the already read in line (ligne) and not the next line?

Also, the reason you get that "odd" output is because Clauses is an array of Strings, so you probably need to use something like Arrays.toString() to get a String representation of it.
Don't use input streams for reading text files. Have a look at the Java™ Tutorials, where you find that a text file is best read with a file reader (or a Scanner). Use try‑with‑resources to close your readers rather than en explicit close() call.
 
Antoine Compagnie wrote:. . . . . .
I shall leave you to work out why you are only using every other line.
I merged your stuff with the following thread. I hope that is okay by you.
Good evening,

I recently learnt how to read line by line a file in char. Yet, I have some issues to add the String lines I read to a String array named clauses
Indeed, with the following code:



I get the following output



The line in between are not the one expected.

Can you help me understand and fiw this issue? Even give me some advises if you think this is a dumb mistake?
It looks like I have the adresses but I'm not sure as far as they are all alike...
See my reply in our other thread:
http://www.coderanch.com/t/661900/java/java/Inserting-map-line-line
Dave Tolls, I did what you advised me to do and it worked, thank you!



I know have

[loves(vincent, mia)., loves(marcellus, mia)., loves(pumpkin, honey_bunny)., loves(honey_bunny, pumpkin)., , jealous(X, Y) :-, loves(X, Z),, loves(Y, Z)., null, null, null, null]


But I don't understand why there are 4 nulls...
Campbell Ritchie, do you mean I should replace



by

No. That code will not work and will probably not even compile because there isn't a buffered reader constructor taking a file. You should also use try with resources as I said yesterday. Did you read the tutorials link I gave you? It has a page telling you how to set up a buffered reader.

As for nulls: what is the size of your array and what is the size of your input file? If they are different you will either exceed the capacity of the array, causing an exception, or you will have unoccupied spaces at the end of the array, which will appear as nulls. You should consider using a List<String> rather than an array to cure that problem.
 
Antoine Compagnie wrote:Campbell Ritchie, do you mean I should replace...

I've gone over this thread, and I have to admit; I'm completely mystified as to what's going on.

You plainly want to read lines from a file an add them to a Map, but all that describes to us is "mechanics".
Why do you want to do this? And why a Map? Why not a List, or a Stack, or a Deque?

My advice: Forget about Java for a moment, and explain to us, in English, what this program is supposed to do. Is it a game? Or some sort of algorithm?

If we knew that, we could probably advise you more; but right now all we can do is help you out with each grammatical problem you run into - and that's a very laborious (and inferior) way to write a program.

HIH

Winston
(1 like)
Okay, your right, I didn't wanted to bother anybody with long explanations about what I was working on and solely asked for technical responses.
But here is what I'm working on:

I am actually creating a prolog terminal, Prolog is based on the resolution of first order predicate. It is based on the resolution principle.

My terminal has to manipulate arithmetic as well as fail cut, write() and read(), it has been advised to use the SWI prolog syntax

For instance:

gives:



  • A prolog file has to be read by my program and printed out with a graphical interface.
  • Arithmetical predicates has to be taken into account
  • Take into account the clauses that have several lines
  • Tests with the example above


  • We will use a class Clause deriving from LinkedList with the inner class Litteral (attributs predicats, listVar) deriving equally from LinkedList with the inner class Symbole.
    Thus, a clause would correspond of an instanciation of the Clause classwhich content would be instances of the class Litteral which content would be instances of the class Symbole
    This last one would represents either variables or alphanumerical constants.
    A symbole would be displayed by its code. It gives access to two information of type Map within the class Annuaire:
  • displaying the symbol
  • and its value

  • If two clauses has the variables X, there wil be nonetheless two symbol in the inner displaying.

    The clause

    will be dsiplayed by a set of instaciations:



    I only coded the main, all the rest was from my teacher.
    In order to do that I have to

  • put the symbols (and only them) in a HashMap
  • Verify that p(X,Y,Z) work with p(U,V,W)
  • know if we are dealing with variables or constants
  • know if it is a case of var/var, const/var, const/ const
  • deal with these cases


  • Here is the whole code from my teacher. I now have to put the symobols into an HashMap, which was the original topic.


    (1 like)
     
    Antoine Compagnie wrote:But here is what I'm working on:...

    OK, thanks for that. Now WE have something to work on.

    It's going to take me a while to go through this (and learn a bit about Prolog), but one thing I can say immediately is that your main() method is FAR too big.

    My advice: Since you're currently dealing with Prolog input - and you're absolutely right to forget about the UI until this is done - create a class called PrologInput (or PrologParser), and transfer ALL the logic that you're currently writing in main() to that.

    This class should take an InputStream and return "prolog-ready" components, such as (I suspect) Clauses and their associated symbol table. You might even want to think about a structure that represents an entire Prolog program.

    Take into account the clauses that have several lines.

    So it sounds to me like (as in Java) a "line" and a "statement" aren't the same thing. So I suspect that this is one of the first things you'll want to do:
    1. Read in lines.
    2. Convert lines to statements (a "statement" being a String that has a 1:1 relationship with a Clause).

    The only thing I would add is that your class should also be able to recognise invalid clauses.

    I'll get back as soon as I've digested your post and have more advice.

    HIH

    Winston
    Okay, thanks for your advises. My main is too long, I developed it myself and it is much more a laboratory than an actual thing, even if the few things to br.close seems to be a good start.

    I do want to read in lines and convert these lines into statements and a Statement is indeed a String that has a 1:1 relationship with a Clause.
    You're right, as in Java, in Prolog a line isn't a statement.
    My point is now to put the symbols (and only them) in HashMaps Annuaire.aff and Annuaire.val to be able to compare two clauses and apply the resolution principle (Horn clause)
    Thank you for your help and advises. I will try to give as much detail as I could.

    Good morning,

    since last time, I did some work:
    I achieved to put the symbols in a hasmap. Actually, thanks to the parsing ri they came as litterals:

    I did:



    And thanks to the toString of Litterals:



    The following came:




    My clause are displayed by:


    Which gives the following:

    [[loves[vincent, mia]], [loves[marcellus, mia]], [loves[pumpkin, honey_bunny]], [loves[honey_bunny, pumpkin]], [loves[X, mia]], [loves[vincent, Y]], [jealous[X, Y], loves[X, Z], loves[Y, Z]], [jealous[U, V]]]


    And the hashmaps:



    Which gives:

    {1=null, 2=null, 3=null, 4=null, 5=null, 6=null, 7=null, 8=null, 9=null, 10=null, 11=null, 12=null, 13=null, 14=null, 15=null, 17=null, 16=null}
    {1=vincent, 2=mia, 3=marcellus, 4=mia, 5=pumpkin, 6=honey_bunny, 7=honey_bunny, 8=pumpkin, 9=X, 10=mia, 11=vincent, 12=Y, 13=X, 14=Y, 15=Z, 17=V, 16=U}


    The code of a symbol is managed since first clause reading as a String. It takes into account Clauses independancy as showed in the following example:



    Variable X of clause 1 is set two times and is stacked by two symbols of same code and the other one has another code because it is independant.
    Here is a sketch of what's going on when reading a file:


    And here on how are they stacked into ListeClauses:



    Now What I have to do is a method boolean unif(Clause c): in Clause that returns true if head of the clause c1 can be unified with head of a clause c2:

    for instance: loves(vincent, mia). (line1) can be unified with loves(X,mia). (line 5)


    there is 3 cases:
  • Constant/Constant: e.g: Mia/Vincent
  • Constant/variable: e.g: Mia/X
  • Variable/variable e.g: X/Y


  • I'm stuck there on how to do Variable/variable: the first variable has to become the second (or the reverse, no matter).

    Here is my new code:


    My, that code is difficult to read. The one design error I can see is frequent use of the keyword static. Why are so many things marked static? If you do not have a good explanation for using the word static, assume it is a serious error. Also why have you got such a long main method?
     
    Antoine Compagnie wrote:Here is my new code: ...

    I hope you don't mind, but I've removed the commented class at the bottom, since it doesn't seem relevant to the problem.

    Indeed, IMO, including commented-out code in general is a really bad habit (and you have at least one other section).
    I realise that you probably put it in there as a reminder for yourself, but there are much better ways to do it.

    My preference: Add a comment line starting with:
      // TO DO ...
    and containing an English (or, in your case, French) description of WHAT the code needs to do.

    Why? Because it reminds you of what you intend to insert, without distracting readers (like us) from what the code actually DOES.
    The "// TO DO" tag is also recognised by some IDEs (like Eclipse; not sure about Netbeans).

    HIH

    Winston
    In my Eclipse IDE, the default is // TODO although you can change it.
    hello, I have such a long main method because I use it to test my methods.
    Many static keywords are from my teacher.
    We did comment but without writing explicitly "TO DO".
    Should we start with a first line commenting all wwhat the code nee to do? Okay, I will do that.
    I'm actually starting to construct the unif method in the class Clause.
    Having made up the predicate/predicate case: for instance loves (X,Y) works with loves(Y,Z),

    I'm now dealing with the 3 symbol cases:
    Constant/Constant: e.g: Mia/Vincent
    Constant/variable: e.g: Mia/X
    Variable/variable e.g: X/Y

    Yet, I have some issues when dealing with them, I will show you.
    Hello!

    Since last time, I've done some hard work and I have now almost finish!

    I can now unify clause to begin a resolution, that is to say, when having:




    with the goal


    To know if Vincent is jealous of Marcellus.

    One can see it how does it works in reality here http://swish.swi-prolog.org/example/examples.swinb by copying and pasting the first code on the left and



    on the right to do it step by step.

    All of the following code are in my main.

    I can do it by hand, that is to say doing:



    First I don't know where does this comes from

    COUCOU jealous[X, Y], loves[X, Z], loves[Y, Z]
    predicat l1 jealous
    predicat l2 jealous
    Annuaire Valeur {1=vincent, 2=mia, 3=marcellus, 4=mia, 5=pumpkin, 6=honey_bunny, 7=honey_bunny, 8=pumpkin, 9=null, 10=mia, 11=vincent, 12=null, 13=null, 14=null, 15=null, 17=marcellus, 16=vincent}
    Annuaire Affichage {1=vincent, 2=mia, 3=marcellus, 4=mia, 5=pumpkin, 6=honey_bunny, 7=honey_bunny, 8=pumpkin, 9=X, 10=mia, 11=vincent, 12=Y, 13=X, 14=Y, 15=Z, 17=marcellus, 16=vincent}
    S1 X
    S1 code 13
    S2 vincent
    S2 code 16
    Variable - Constante
    Annuaire Valeur {1=vincent, 2=mia, 3=marcellus, 4=mia, 5=pumpkin, 6=honey_bunny, 7=honey_bunny, 8=pumpkin, 9=null, 10=mia, 11=vincent, 12=null, 13=vincent, 14=null, 15=null, 17=marcellus, 16=vincent}
    Annuaire Affichage {1=vincent, 2=mia, 3=marcellus, 4=mia, 5=pumpkin, 6=honey_bunny, 7=honey_bunny, 8=pumpkin, 9=X, 10=mia, 11=vincent, 12=Y, 13=vincent, 14=Y, 15=Z, 17=marcellus, 16=vincent}
    S1 Y
    S1 code 14
    S2 marcellus
    S2 code 17
    Variable - Constante
    HOLALALALALALALA true


    I tried to modified the code a bit with



    Last, but definitely not least, I now would like to do it automaticaly, that is to say to do this resolution automaticaly. I tried:



    Which is inspired a lot from the "by hand method". Yet, it doesn't work because of an IndexOutOfBoundsException at line 60.

    I notified in the comments where I think it bugs.
    Can you help me debugging/understanding this error? I understand what IndexOutOfBoundsException issuer is, And I've written in the comments where it is created, but I want to know it doesn't work in the automate method, because it worked in the by hand one.
    I think I am pretty close from the solution. My teacher then send me a blueprint for the automatical method:

    IR: résolution indice
    ICF: goald indice
    INDEX array giving the number of the clause used to construct the unified clause "la résolvante".



    Can you help me building up from this this loop that would automate the project?

    As a reminder, this is my whole new code:


    Please don't write such long lines. I have sorted out the worst offenders, so you can see how to do it in future  Don't use all those // comments because they make the lines longer. A // comment should be very short; those comments should be put on their own lines and changed to /* comments */
    Could you post the entire stack trace of error?
    Of course for the error code:!

    And sorry for long lines, I just did a Ctrl+I and will try to short my lines in the future.

    here it is
     
    Antoine Compagnie wrote:Last, but definitely not least, I now would like to do it automaticaly, that is to say to do this resolution automaticaly. I tried:
    Which is inspired a lot from the "by hand method". Yet, it doesn't work because of an IndexOutOfBoundsException at line 60.

    OK, well the only section of that method that seems to use get() is this one:and since the error message is telling you that the size is 0, it would appear that Clause.ListeClauses is empty. But why that is, I have no idea.

    You could do yourself a lot of favours by
    (a) spacing out your code a bit (as I've done above). Right now it's very difficult to read.
    (b) making ListClauses a List<Clause> instead of just a List. That would save you having to cast every time you get() a value.

    I'm also a little puzzled by that section above:
  • First you set ir to the index of the last element in ListClauses (or -1 if it's empty).
  • Next you create a loop that goes through every element except the last one.
  • Next you set 'goal' to the element before the last one.
  • Then you do a bunch of other stuff.

  • It seems incredibly tortuous to me; and plainly isn't going to work if ListClauses has less than two elements in it - which is definitely the case here.

    Why don't you back up a bit and think about what that loop is supposed to do? It seems to me that you're just adding more and more code with no real plan.

    Winston
    First :ir Resolution Indice: is where the goal is. It will increase as far as we are creating new goals through resolutions.

    Next, I loop over every line but the last one, that's okay as far as we are first looking for the first possible clause to unify with the goal.

    Next you set 'goal' to the element before the last one.



    Should I do



    to set is as the goal?

    plainly isn't going to work if ListClauses has less than two elements in it - which is definitely the case here.


    Okay, listClause have to have two elements. Else remove(0) will leave and empty collection.
    Yet, why was it working during the by hand method? Actually when I have


    I have to have after unif, remove andall:


    Here is what I did with the byhand method.


    And if I do



    I get:



    Which is almost what I want, it lacks Y transformation.
     
    Antoine Compagnie wrote:Should I do

    to set is as the goal?

    I suspect so, but what you really need to do is step back from the problem and ask yourself this:
      WHAT is that loop trying to do?
    and write down answer in English (or French).

    It seems to me that your approach is rather "existential", and while Jean-Paul Sartre was a great Frenchman, he would not have made a great programmer.

    This is is a difficult problem, so you're not going to solve it simply by coding. You need some structure to that code (and very likely to the objects in it); but in order to get there, you first need to understand the problem as a whole rather than just tackling it as a coding exercise.

    Just to give you an idea: If this was me, and since I don't know much about Prolog, I would probably have spent at least a week (and possibly a month) reading about the language, drawing diagrams, and writing out definitions and scenarios. I'd want to understand exactly what makes a Prolog program tick, and how the various elements of clause, fact, variable and term fit together before I wrote my first line of code.

    Unfortunately, you're a long way down the "coding" path, and I suspect you have a lot of time and effort invested in it. And that is precisely what I see - a lot of code. It looks brittle and monolithic, and difficult to change and understand; so the only things I can suggest for advice are some simple guidelines:
  • Stop Coding.
  • No method - including main() - should be longer than 20 lines; and preferably shorter.
  • Don't be afraid of creating classes. You appear to have 3, where I would expect around a dozen (6 at the very least).
  • Don't make anything static unless you have a VERY good reason.

  • Sorry if this sounds harsh, but I honestly think you're headed for trouble. You might get a program that works, but it'll only be after a lot of blood, sweat and tears. And even then, it's likely to be difficult to change later on if you need to.

    HIH

    Winston
    You were right!

    I just stop coding for a day did some tests on some Prolog examples.

    The loop was awful, I did it again
    after testing my code bit by bit I noticed that the error was that i didn't did all what was needed to to do the unifcation.
    The constant vs variable part was missing the Symbol diplaying modifications after unifying:



    Now, it's almost done. All I have to do is to loop over the loop with a while until the goal can't be unified anymore with any clauses.
    To do that I will have to add a goal each time I unify and exit the inner loop to iterate again over the clauses.


    I liked you joke on Jean-Paul!
    I will post my code when I think it will be ready enough for facing your judgments. Actually my main has only 40 lines of really used code! The rest is ruins of avorted ideas that can still help me!
    Okay, here it is, the first version to work:

    Alas! it only work for simple resolution questions. It semms not to be okay for more complex programs such as

  • write,nl
  • rules


  • This file projet.pl with the question asked on the last line, I mean if vincent is jealous of Marcellus, would work.



    Whereas this one: magasin.pl wouldn't as far as there are now new thing to apply such as write and new line.



    Furthermore, my teacher told me my code would not gives right answers if I had to apply it on example such as:



    In the first example they are not used. They mean everybody loves mia and vincent loves everybody.

    No need to wait more, I'm giving you this code and the one my teacher gived me if I wasn't able to cope with this two new challenges.



    Therefore the following one is from my teacher, one as to notice that he used array for ListeClauses rather than LinkedList.
    It allows him to do something I can't that is to say to add his new resolution clause furhter down and to navigate better between, step by step when they can't be unified.


     
    Antoine Compagnie wrote:the following one is from my teacher

    Sorry, but I can't say that I'm impressed. That code does not meet my standards for readability or for basic "cleanliness". The fact that an instructor gave this to his/her students just confirms my belief that folks in academia are out of touch with industry best practices and are contributing to the problem of bad code flooding our applications in the real world.
    I know... :'(

    But... I have to use it anyway. Mine does the work but isn't really cleaner!

    I added in his code



    and received:



    I'm quite depressed letting my code for his own... But I think this is common in the industry...I will make it!
     
    Antoine Compagnie wrote:Alas! it only work for simple resolution questions. It semms not to be okay for more complex programs such as
  • write,nl
  • rules

  • And what's that supposed to do?

    I'm afraid that the problem for me is that I simply don't understand enough about Prolog to advise you; so the "program" above simply looks like gibberish to me.
    If I had a few weeks to spend learning the language and understanding the relationships between clauses, literals and symbols and how they are used when posed a query, it would be different - but unfortunately, I don't.

    What I can say is that I don't like your teacher's program at all - even if it does work.
  • It's messy (ie, badly organised, with methods, constructors and member class declarations mixed together apparently at random).
  • It's badly documented - actually not documented at all, AFAICS.
  • It doesn't use generics, so it contains several "raw" Lists.
  • The entire logic is crammed into one file, including a double-nested inner class (Clause→Litteral→Symbole) - something I've never seen before.
  • It contains far too many static methods for my liking.
  • It accesses class internals (almost none of which are private) directly, rather than via "getter" methods.
  • Clause contains a static array of clauses (ListeClauses).
    Even presuming that such a thing is desirable, wouldn't it be better to make it a List (or actually, a List<Clause>)?

  • Now some things (like the lack of documentation) may be deliberate, but the rest is not.
    However, since it's what you've been given, here's my suggestion:
    1. Print out a copy of each and place them side-by-side.
    2. Go through them both, trying to work out what it is that your teacher has done differently to you, especially in some of the loops; and particularly the analyse(), parsingClause() and unif() methods.

    It might at least point out some of your logic errors, and explain why your program doesn't work in all cases (assuming that your teacher's does).

    HIH

    Winston
    Thank you for still consideing my issues then!

    I will try to use your advises to improve his code.

    His code doesn't do all the work. He left some things in order to let us work on it such as the var var case const/const or the rules...

  • write is used to write the given clause


  • nl print a new line




  • We will have for instance


    Which means Shop Youpi! located in Paris.

  • rules ar special cases when there is variables in a clause which is not the goal



  • Here it means that everybody loves mia and vincent loves everybody.

    All of this has to be written out when unification is done, that is to say when boolean unif(Clause c) is called.
    Dear all,

    this is almost done. Thanks for all your support and help. I have to finish it for Tuesday then it will be done. I'm able to deal with the following files apart from the love/hate relationship:

    A way to know which stores are located in which cities:


    Yet, I'm not able to deal with the "cut/!", which makes a Clause readable only once.



    But that's not the most important. The most important is that I have yet to deal with the predicate :- which precise what a clause is made of.
    It seems from SWISH that even if the goal has the same litteral than the first clause it has firs to unify with the one with ":-"
    I tried during hours to make it work the right way but still
    My last will here on this topic is your help to revert this loop, to make it clear for the program to start with :- clause:


    For example let's take the multiplication of 2 by 3


    if unifying with the first clause it would give write(R) has an output with nothing in it.
    The second case would give 6, the actual result of the multiplication of 2 by 3.

    I'm going to give you my code but in order to change the step by step method to the classic display method, two variables have to be modified: display and caseDisplay which are boolean

    The first one shows how does the resolution is being processed clause by clause.
    The second one shows how does cases are managed.

    The for loop I am talking about is the following one:



    IR is the Resolution indice, the goal is copieResolvante, courante is each clause we are testing (and we want to test the from the bottom to the top).

    Here is the whole code, the file has to be placed in with the name you will give him instead of exercice4.pl and placed at the root of the workspace.

    Enough speaking. If you're willing to help me and I would be very grateful!!!



    Two other files are associated: the class Couples...



    And the class Symbol



    I still have to create a manager GUI interface in order to make this thing user friendly.
    Wink, wink, nudge, nudge, say no more ... https://richsoil.com/cards



    All times above are in ranch (not your local) time.
    The current ranch time is
    May 25, 2017 08:58:37.