[Prolog] Dezimal zu Text umwandeln

Heinzi1991

Erfahrenes Mitglied
#1
Also ich hab ja schon ein Thema gepostet, in dem ich ein Prädikat schreiben musste, dass zeilenweise aus einer Datei einlesen kann und in eine Liste speichern kann.

Das hab ich schon geschafft, aber jetzt hab ich das Problem das in meinen Listen keine 1er und 0len stehen sondern die Dezimalzahlen von 0, 1 und dem Leerzeichen, aber ich weiß nicht wie ich das jetzt umwandeln kann, damit der Text wieder da steht.

Ich darf jedes vorprogrammierte Prädikat, dass Prolog versteht verwenden, mir wurde der Tipp gegeben die Prädikate tokenize_atom, nth0, nth1 und maplist könnten helfen, aber ich weiß nicht wie.

Hoffe mir kann jemand auf die Sprünge helfen.
 

Parantatatam

mag Cookies & Kekse
#2
Du kannst doch einfach für jede Ziffer ein Prädikat erstellen, welches als "Eingabe" den Wert als Text und als "Ausgabe" den Wert als Zahl hat:
Code:
convert( "0", 0 ).
convert( "1", 1 ).
Und kannst es dann so anwenden:
Code:
:-? convert( "0", A ).
A = 0;
 

Heinzi1991

Erfahrenes Mitglied
#3
ok schaut eig sehr nice aus, aber wie baue ich das in meinen code ein:

hier ist der code:
Code:
readFile(FileInput, TextList):- open(FileInput, read, Stream),
                                readCharacter(Stream, TextList),
                                close(Stream),
                                !.


readCharacter(Stream,[]):- at_end_of_stream(Stream).    % Exit condition


readCharacter(Stream,[Char|Tail]):- read_line_to_codes(Stream, Char),
                                    readCharacter(Stream,Tail).
 

Parantatatam

mag Cookies & Kekse
#4
Was steht denn jetzt in TextList drin? Das müsste doch eine Liste mit einzelnen Zeichen sein oder täusche ich mich? Kannst Du mal einen Abriss eines möglichen Ergebnisses davon teilen?
 

Heinzi1991

Erfahrenes Mitglied
#5
also ein kleiner teil meines ergebnisses:

Code:
?- readFile('demograph.grf', LSS).
LSS = [[48, 32, 49, 32, 48, 32, 48, 32|...], [49, 32, 48, 32, 48, 32, 49|...],
 

Parantatatam

mag Cookies & Kekse
#6
Es ist also eine Liste von ASCII-Codes. Obwohl Zeichenketten in Prolog immer so aussehen.
 

Heinzi1991

Erfahrenes Mitglied
#7
ja aber irgendwie will ich jetzt das am schluss so was steht:

Code:
?- readFile('demograph.grf', LSS).
LSS = [[0, 1, 0, 1,|...], ......
also das die ASCII Zeichen verschwinden und es sollen auch die Leerzeichen "32" verschwinden, es sollen in den Listen nur 1 und 0 drinnen stehen
 

Parantatatam

mag Cookies & Kekse
#8
Leider wusste ich ad hoc nicht, wie man in Prolog eine Zeichenkette in eine Liste umwandelt, aber wenn man die Zeichenkette als Liste vor sich hat, dann geht es beispielsweise so:
Code:
convert_atom( "0", 0 ).
convert_atom( "1", 1 ).
convert_atom( " ", " " ).

convert( [] | [] ).
convert( [ Char | InputRest ], [ Int | OutputRest ] ) :- convert_atom( Char, Int ), convert( InputRest, OutputRest ).
Du musst natürlich auch noch überlegen, was Du mit den Leerzeichen machst. Ich habe es hier so gelöst, dass sie einfach Leerzeichen bleiben. Falls Du sie entfernen willst, gibt es da unterschiedliche Methoden.
 

Heinzi1991

Erfahrenes Mitglied
#9
ok hab es jetzt probiert, aber ich bekomm immer einen "out of local stack" oder einen "out of global stack", wo genau muss ich das prädikat convert einbauen?
 

Parantatatam

mag Cookies & Kekse
#10
Was mich bei Deinem Beispiel wundert, sind zwei Sachen: einerseits sind es mehrere Listen, die wiederum in einer sie umfassenden Liste sind, andererseits der Listenoperator, den Du dort immer vor den drei Punkten hast. Wie kommt die Ausgabe jetzt direkt von readFile/2 ?
 

Heinzi1991

Erfahrenes Mitglied
#11
Also meine Aufgabenstellung sieht so aus das ich eine Liste mit mehreren Listen ausgeben muss, die wiederum mit 0/1 Elementen befühlt ist. Also stimmt ja eigentlich bei mir, nur halt im ASCII - Code.
Und das mit den Listenoperator vor den drei Punkten, ist das er einfach nicht alles aufschreibt, keine Ahnung warum eigentlich. Meine Datei hat nein Zeilen, jeder kleine Liste steht für eine Zeile, in der neunten Liste steht dann nur mehr [ ... | ... ].
 

Parantatatam

mag Cookies & Kekse
#12
Jetzt weiß ich, wie Du Dir die Daten ausgeben lässt. Es ist üblich in Prolog, dass Zeichenketten als Listen von ASCII-Codes ausgegeben werden und dass längere Listen ab einem gewissem Punkt angekürzt werden. Jedoch kann ich Dir auf Anhieb auch nicht sagen, wie Du Dir alles mit einmal ausgeben lassen kannst, so dass Du alles so siehst, wie Du es gerne hättest.

Prinzipiell musst Du auf jede Zeile convert/2 anwenden, damit Du am Ende eine Liste von Listen hast, in denen die Werte dann als Nullen und Einsen stehen.
Code:
each_line( [] | [] ).
each_line( [ InputLine | InputRest ], [ OutputLine | OutputRest ] ) :- convert( InputLine, OutputLine ), each_line( InputRest, OutputRest ).
Code:
? :- readFile( 'demograph.grf', LSS ),each_line( LSS, ConvertedLines ).
ConvertedLines = [[0, " ", 1, " ", 0, " ", 0, " "|...], [1, " ", 0, " ", 0, " ", 1|...],
Übrigens scheint es bei Deinen Daten so zu sein, dass jedes zweite Zeichen ein Leerzeichen ist und somit quasi als Trennzeichen zwischen den Nullen und Einsen steht, was ich persönlich für sehr überflüssig halte, wenn es nur Nullen und Einsen sind. Aber das nur am Rand.
 

Heinzi1991

Erfahrenes Mitglied
#14
ok das mit dem konvertieren funktioniert nicht so einfach; aber ich hab ein bisschen im internet gesucht, und bin auf was interessantes gestoßen, was ich in meiner angabe komplett überlesen habe. in der Datei die ich einlesen muss, ist eine adjazenzmatrix und diese muss ich dann ausgeben, die frage ist nur wie! ;)
 

Parantatatam

mag Cookies & Kekse
#15
Laut Dokumentation gibt es im SWI-Prolog ein Prädikat string_to_list/2 mit dem Du eine Zeichenkette in eine Liste umwandeln kannst. Ansonsten müsste das alles so stimmen. Oder wo tritt bei Dir der Fehler auf?