Da die letze Version dieses Programms (Chatbot kann man das eigentlich nicht mehr nennen) sowohl sprachlich als auch im Bereich Logik sehr eingeschränkt war werde ich natürlich weiterhin versuchen das System so gut wie möglich zu verbessern. Da es scheint als würden sich diese beiden Punkte gegenseitig ausschließen habe ich mit der Logik angefangen, einfach weil es um einiges einfacher ist.
Das Resultat könnte man fast als Prolog Interpreter bezeichnen, auch wenn die Syntax minimal anders ist und nicht alle Features vorhanden sind. So haben wir aber im Vergleich zur alten Version jetzt die Möglichkeit mehrere Bedingungen durch logische Operatoren zu verknüpfen. Außerdem können Funktionen (fast) beliebig ineinandergeschachtelt werden.
Spoiler anzeigen
Func UnnamedFunction($sQuestion, $sData)
Local $reFact = "(?m)^([a-z]+\((?:[A-Za-z]+,)*[A-Za-z]+\))\."
Local $reQuestion = "([a-z]+\((?:[a-z]+,)*[a-z]+\))"
Local $reRule1 = "(?m)^\Q%s=\E([A-Za-z(),]+)\s*$"
Local $reRule2 = "(?m)^%s\(((?:[A-Z][A-Za-z]*,)*[A-Z][A-Za-z]*)\)=([A-Za-z(),]+)$"
; remove
$sQuestion = StringRegExpReplace($sQuestion, "\s+", "")
$sData = StringReplace($sData, @CR, "")
$sData = StringRegExpReplace($sData, "(?m)//.*$", "")
$sData = StringRegExpReplace($sData, "(?s)/\*.*?\*/", "")
$sData = StringRegExpReplace($sData, "\h+", "")
; expand
$sData = StringRegExpReplace($sData, $reFact, "\1=true")
; evaluate
Local $_, $aQuestion, $i, $aRule, $aFormula, $sBody, $j
For $_ = 1 To 100
$aQuestion = StringRegExp($sQuestion, $reQuestion, 3)
If (Not @error) Then
For $i = 0 To UBound($aQuestion)-1
$aRule = StringRegExp($sData, StringFormat($reRule1, $aQuestion[$i]), 3)
If @error Then
$aFormula = StringRegExp($aQuestion[$i], "([a-z]+)", 3)
$aRule = StringRegExp($sData, StringFormat($reRule2, $aFormula[0]), 3)
If @error Then
; critical - remove if necessary
If (StringRegExp($aQuestion[$i], "([a-z]+)\(\1\)", 0) = 1) Then
$sQuestion = StringReplace($sQuestion, $aQuestion[$i], "true", 0, 1)
Else
$sQuestion = StringReplace($sQuestion, $aQuestion[$i], "false", 0, 1)
EndIf
Else
$sBody = $aRule[1]
$aRule = StringRegExp($aRule[0], "([A-Z][A-Za-z]*)", 3)
If (UBound($aRule) <> UBound($aFormula)-1) Then Return SetError(2, 0, $sQuestion)
For $j = 0 To UBound($aRule)-1
$sBody = StringRegExpReplace($sBody, "\b" & $aRule[$j] & "\b", $aFormula[$j+1])
Next
$sQuestion = StringReplace($sQuestion, $aQuestion[$i], $sBody, 0, 1)
EndIf
Else
$sQuestion = StringReplace($sQuestion, $aQuestion[$i], $aRule[0], 0, 1)
EndIf
Next
EndIf
If (StringInStr($sQuestion, "(") = 0) Then ExitLoop
Next
; return
Return $sQuestion
EndFunc
Ein Skript in dieser "Programmiersprache" würde nun folgendermaßen aussehen:
and(true, true).
or(true, true).
or(true, false).
or(false, true).
not(false).
xor(true, false).
xor(false, true).
Beachten sollte man hierbei, dass von jedem Ausdruck der nicht bewiesen werden kann automatisch angenommen wird, dass er falsch ist. Somit können wir and in nur einer statt den üblichen vier Zeilen definieren.
Das Beispiel mit den Vögeln (falls jemand ein kreativeres Beispiel hat nur her damit) könnte man zum Beispiel so implementieren (in Englisch, da Umlaute nicht unterstützt werden):
04.08.2014: Ich habe den ursprünglichen Inhalt dieses Posts jetzt endgültig entfernt, da das Skript wie schon des öfteren erwähnt (leider) nichts mit künstlicher Intelligenz zu tun hat. Ich hoffe das stört niemanden, aber da die Verwendung von INI Dateien sowieso aus irgendeinem Grund Probleme verursacht hatte war das sowieso nicht wirklich von Wert. Version 2, die (wenn auch sehr sehr eingeschränkt) logisches Denken unterstützt, ist weiterhin in Post 9 zu finden. Da die Kommentare #2 bis #8 sich größtenteils auf Version 1 beziehen ist es besser diese direkt zu überspringen und bei Version 2 weiterzulesen.