Modification to the above script (adding !facts command) plus some examples on how to use the script
Code: Select all
# learn.tcl
# to add a fact and definition in learn.txt
# you must use -> shown in the syntax below to seperate the fact from the definition
# !learn fact -> definition
# to recall the definition for fact
# firstly tries an exact match then the smallest partial match beginning with fact
# !recall fact
# to remove any record exactly matching fact from learn.txt
# !unlearn fact
bind PUB - !facts pLearnFacts
bind PUB - !learn pLearnLearn
bind PUB - !recall pLearnRecall
bind PUB - !unlearn pLearnUnlearn
set vLearnVersion 2.0
proc pLearnError {number nick chan {arg1 ""}} {
set prefix (\00304$nick\003)
switch -- $number {
01 {set output "Incorrect syntax, use \00312!learn fact -> definition\003"}
02 {set output "A definition already exists \00312$arg1\003"}
03 {set output "Nothing found for \00312$arg1\003"}
04 {set output "The characters \00312->\003 can only be used once to seperate the fact from the definition"}
05 {set output "Incorrect syntax, use \00312!facts\003 without additional arguments"}
06 {set output "No facts currently in the database"}
default {}
}
putserv "PRIVMSG $chan :$prefix $output"
return 0
}
proc pLearnFacts {nick uhost hand chan text} {
global vLearnData
if {[llength [split [string trim $text]]] == 0} {
pLearnRead
if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
pLearnOutput 05 $nick $chan [llength $vLearnData]
} else {pLearnError 06 $nick $chan}
unset -nocomplain -- vLearnData
} else {pLearnError 05 $nick $chan}
return 0
}
proc pLearnLearn {nick uhost hand chan text} {
global vLearnData
set record [regsub -all -- {[\s]{2,}} [string trim $text] { }]
if {[regexp -- {^(.+) -> } $record -> fact]} {
if {[regexp -all -- {->} $record] == 1} {
pLearnRead
if {[set found [pLearnSearchFull $fact]] == 0} {
pLearnWrite $record
pLearnOutput 01 $nick $chan $record
} else {pLearnError 02 $nick $chan [lindex $found 1]}
unset -nocomplain -- vLearnData
} else {pLearnError 04 $nick $chan}
} else {pLearnError 01 $nick $chan}
return 0
}
proc pLearnOutput {number nick chan {arg1 ""}} {
set prefix (\00303$nick\003)
switch -- $number {
01 {set output "Learnt \00312$arg1\003"}
02 {set output "Found full match \00312$arg1\003"}
03 {set output "Found partial match \00312$arg1\003"}
04 {set output "Unlearnt \00312$arg1\003"}
05 {set output "Current database size \00312$arg1\003 fact(s)"}
default {}
}
putserv "PRIVMSG $chan :$prefix $output"
return 0
}
proc pLearnRead {} {
global vLearnData
if {[file exists learn.txt]} {
set fp [open learn.txt r]
set vLearnData [split [read -nonewline $fp] \n]
close $fp
}
return 0
}
proc pLearnRecall {nick uhost hand chan text} {
global vLearnData
set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
pLearnRead
if {[set result [pLearnSearchFull $fact]] != 0} {
pLearnOutput 02 $nick $chan [lindex $result 1]
} elseif {[set result [pLearnSearchPartial $fact]] != 0} {
pLearnOutput 03 $nick $chan $result
} else {
pLearnError 03 $nick $chan $fact
}
unset -nocomplain -- vLearnData
return 0
}
proc pLearnSearchFull {fact} {
global vLearnData
if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
for {set position 0} {$position < [llength $vLearnData]} {incr position} {
if {[string match -nocase "$fact -> *" [lindex $vLearnData $position]]} {
set found [list $position [lindex $vLearnData $position]]
break
}
}
}
if {[info exists found]} {return $found} else {return 0}
}
proc pLearnSearchPartial {fact} {
global vLearnData
if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
set vLearnData [lsort -increasing $vLearnData]
foreach record $vLearnData {
if {[string match -nocase "$fact* -> *" $record]} {
set found $record
break
}
}
}
if {[info exists found]} {return $found} else {return 0}
}
proc pLearnUnlearn {nick uhost hand chan text} {
global vLearnData
set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
pLearnRead
if {[set found [pLearnSearchFull $fact]] != 0} {
set vLearnData [lreplace $vLearnData [lindex $found 0] [lindex $found 0]]
set fp [open learn.txt w]
if {[llength $vLearnData] != 0} {
puts $fp [join $vLearnData \n]
}
close $fp
pLearnOutput 04 $nick $chan [lindex $found 1]
} else {pLearnError 03 $nick $chan $fact}
unset -nocomplain -- vLearnData
return 0
}
proc pLearnWrite {record} {
set fp [open learn.txt a]
puts $fp $record
close $fp
return 0
}
putlog "learn.tcl version $vLearnVersion loaded"
# eof
The command !facts will output the currect database size
<@arfer> !facts
<@osmosis> (
arfer) No facts currently in the database
The command !facts is used without additional arguments
<@arfer> !facts 1
<@osmosis> (
arfer) Incorrect syntax, use
!facts without additional arguments
The command !learn fact -> definition will add a fact (and its definition) to the database
<@arfer> !learn The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@osmosis> (
arfer) Learnt
The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@arfer> !facts
<@osmosis> (
arfer) Current database size
1 fact(s)
The same exact fact cannot be duplicated in the database, even with a different definition
<@arfer> !learn The Usual Suspects -> whatever
<@osmosis> (
arfer) A definition already exists
The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
The above is true irrepective of the case
<@arfer> !learn THE uSUal SUSPECts -> whatever
<@osmosis> (
arfer) A definition already exists
The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
Inexact facts, even with the same definition, would not be considered duplicates
<@arfer> !learn Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@osmosis> (
arfer) Learnt
Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@arfer> !facts
<@osmosis> (
arfer) Current database size
2 fact(s)
The command !learn fact -> definition must be used exactly as shown, with the characters " -> " seperating the fact from the definition
<@arfer> !learn K-PAX-> A film with Kevin Spacey
<@osmosis> (
arfer) Incorrect syntax, use
!learn fact -> definition
<@arfer> !learn K-PAX ->A film with Kevin Spacey
<@osmosis> (
arfer) Incorrect syntax, use
!learn fact -> definition
<@arfer> !learn K-PAX, A film with Kevin Spacey
<@osmosis> (
arfer) Incorrect syntax, use
!learn fact -> definition
<@arfer> !learn K-PAX -> A film with Kevin Spacey
<@osmosis> (
arfer) Learnt
K-PAX -> A film with Kevin Spacey
<@arfer> !facts
<@osmosis> (
arfer) Current database size
3 fact(s)
The characters -> cannot be used elsewhere in the !learn command, within the fact or definition
<@arfer> !learn Elephant -> A large mammal -> African or Asian varieties exist
<@osmosis> (
arfer) The characters
-> can only be used once to seperate the fact from the definition
The command !unlearn fact is used to remove the fact exactly, irrespective of case
<@arfer> !unlearn usuaL
<@osmosis> (
arfer) Nothing found for
usuaL
<@arfer> !unlearn usuaL suspects
<@osmosis> (
arfer) Unlearnt
Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@arfer> !facts
<@osmosis> (
arfer) Current database size
2 fact(s)
The command !recall fact will look for an exact match, irrerspective of case, or if not found the smallest partial match beginning with fact
<@arfer> !recall k-PAx
<@osmosis> (
arfer) Found full match
K-PAX -> A film with Kevin Spacey
<@arfer> !recall k
<@osmosis> (
arfer) Found partial match
K-PAX -> A film with Kevin Spacey
The command !recall fact will not find anything smaller than the specified fact
<@arfer> !recall k-PAx film
<@osmosis> (
arfer) Nothing found for
k-PAx film