using System; using JJC.Psharp.Lang; using JJC.Psharp.Predicates; using System.Xml; using System.Collections; using System.Net; using System.Net.Sockets; using System.IO; using System.Reflection; namespace DCAServer { /// /// Summary description for Class1. /// class PredicateDescriptor { public string name; public ArrayList key; public PredicateDescriptor( string name, ArrayList key ) { this.name = name; this.key = key; } } class DCAServer { static ArrayList predicates; public static PushbackReader GetStringReader( string s ) { StringReader sr = new StringReader( s ); return new PushbackReader( (TextReader)sr ); } static void ReadTable( XmlTextReader reader ) { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if( reader.Name.Equals( "predicate" ) ) { ReadPredicateData( reader, reader.GetAttribute( "name" ) ); } else throw new Exception( ); break; case XmlNodeType.EndElement: break; case XmlNodeType.Whitespace: break; default: throw new Exception( ); } } } static void ReadPredicateData( XmlTextReader reader, string name ) { ArrayList key = new ArrayList( ); while( reader.Read( ) ) { switch( reader.NodeType ) { case XmlNodeType.Element: if( reader.Name.Equals( "field" ) ) { string isKey = reader.GetAttribute( "key" ); key.Add( isKey ); reader.Read( ); if( !( reader.Name.Equals( "field" ) ) || !( reader.NodeType == XmlNodeType.EndElement ) ) throw new Exception( ); } else throw new Exception( ); break; case XmlNodeType.EndElement: if( !reader.Name.Equals( "predicate" ) ) throw new Exception( ); else { predicates.Add( new PredicateDescriptor( name, key ) ); return; } case XmlNodeType.Whitespace: break; default: throw new Exception( ); } } } static void ReadXMLFile( string file ) { XmlTextReader reader = new XmlTextReader( file ); reader.WhitespaceHandling = System.Xml.WhitespaceHandling.Significant; try { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if( reader.Name.Equals( "dcatable" ) ) ReadTable( reader ); else throw new Exception( ); break; case XmlNodeType.EndElement: break; case XmlNodeType.Whitespace: break; default: throw new Exception( ); } } } finally { if( reader != null ) reader.Close(); } } [STAThread] static void Main(string[] args) { predicates = new ArrayList( ); // args[0] should be a file, we will load the // schema for the data therefrom (maybe this should be XML). if( args.Length != 1 ) { Console.WriteLine( "Usage: DCAServer " ); return; } string file = args[ 0 ]; ReadXMLFile( file ); // now dump all this data into the prolog engine, // so that it can assert relevant predicates. PrologInterface sharp = new PrologInterface( ); sharp.addCallingAssembly( ); sharp.setPredicate( new JJC.Psharp.Predicates.DcaInit_0( new ReturnCs( sharp ) ) ); sharp.call( ); SymbolTerm key = SymbolTerm.makeSymbol( "key", 0 ); SymbolTerm nonkey = SymbolTerm.makeSymbol( "nonkey", 0 ); for( int i = 0; i < predicates.Count; i++ ) { PredicateDescriptor pd = (PredicateDescriptor) (predicates[ i ] ); string s = pd.name; ArrayList k = pd.key; Term lt = SymbolTerm.makeSymbol( "[]", 0 ); for( int j = k.Count - 1; j >= 0; j-- ) { if( ((string)k[ j ]).Equals( "true" ) ) lt = new ListTerm( key, lt ); else lt = new ListTerm( nonkey, lt ); } sharp.setPredicate( new DcaAssertPred_3( SymbolTerm.makeSymbol( s ), new IntegerTerm( k.Count ), lt, new ReturnCs( sharp ) ) ); sharp.call( ); } /* args = new string[] { "Cafeteria" }; if( args.Length == 0 ) args = new string[] { "Main" }; Assembly a = System.Reflection.Assembly.Load( "Psharp" ); a.GetType( "JJC.Psharp.Lang.PrologMain" ).GetMethod( "Main" ). Invoke( a.CreateInstance( "JJC.Psharp.Lang.PrologMain" ), new object[] { args } ); */ RunServer( ); } public static void BroadCast( string tb ) { Console.Out.WriteLine( "Broadcast: " + tb ); try { BroadCast( tb, 6001 ); } catch { } try { BroadCast( tb, 6002 ); } catch { } try { BroadCast( tb, 6003 ); } catch { } try { BroadCast( tb, 6004 ); } catch { } } public static void ResetAllPorts( object lt ) { try { ResetAgents( lt, 6001 ); } catch { } try { ResetAgents( lt, 6002 ); } catch { } try { ResetAgents( lt, 6003 ); } catch { } try { ResetAgents( lt, 6004 ); } catch { } } public static void BroadCast( string tb, int port ) { TcpClient client = null; NetworkStream output = null; BinaryWriter writer = null; try { client = new TcpClient( ); client.Connect( "localhost", port ); output = client.GetStream( ); writer = new BinaryWriter( output ); writer.Write( tb ); } finally { try { writer.Close( ); } catch { } try { output.Close( ); } catch{ } try { client.Close( ); } catch { } } } public static void ResetAgents( object lt, int port ) { TcpClient client = null; NetworkStream output = null; BinaryWriter writer = null; try { client = new TcpClient( ); client.Connect( "localhost", port ); output = client.GetStream( ); writer = new BinaryWriter( output ); writer.Write( "broadcast_all." ); Term result = ((ListTerm)lt).dereference( ); Term elm; for ( ; ; ) { elm = ((ListTerm)result).car.dereference(); writer.Write( "broadcast_assert( " + elm.ToString( ) + ". )." ); result = ((ListTerm)result).cdr.dereference(); if( !( result is ListTerm ) ) break; } writer.Write( "end." ); } catch( Exception e ) { } finally { try { writer.Close( ); output.Close( ); client.Close( ); } catch { } } } public static void BroadcastAssertTerm( Term t ) { BroadCast( "broadcast_assert( " + t + ". )." ); } public static void BroadcastAssert( string tba ) { BroadCast( "broadcast_assert( " + tba + " )." ); } public static void BroadcastRetract( string tbr ) { BroadCast( "broadcast_retract( " + tbr + " )." ); } public static void BroadcastAllRetract( ) { BroadCast( "all_retract." ); } public static object databaseLock = new object( ); public static void DoAssert( string tba ) { lock( databaseLock ) { PrologInterface sharp = new PrologInterface( ); sharp.setPredicate( new DcaAssert_1( SymbolTerm.makeSymbol( tba ), new ReturnCs( sharp ) ) ); sharp.call( ); } } public static void DoRetract( string tbr ) { lock( databaseLock ) { PrologInterface sharp = new PrologInterface( ); sharp.setPredicate( new DcaRetract_1( SymbolTerm.makeSymbol( tbr ), new ReturnCs( sharp ) ) ); sharp.call( ); } } public static string Strip( string sin ) { int i = sin.IndexOf( "(" ); int j = sin.LastIndexOf( ")" ); string sout = sin.Substring( i + 2, j - i - 3 ) + "."; return sout; } public static object resolveConflictLock = new object( ); public static int ResolveConflict( object lt, object r, object w ) { lock( resolveConflictLock ) { BinaryReader reader = (BinaryReader)(r); BinaryWriter writer = (BinaryWriter)(w); writer.Write( "conflicts." ); Term result = ((ListTerm)lt).dereference( ); Term elm; for ( ; ; ) { elm = ((ListTerm)result).car.dereference(); writer.Write( elm.ToString( ) + "." ); result = ((ListTerm)result).cdr.dereference(); if( !( result is ListTerm ) ) break; } writer.Write( "!conflicts." ); string s = reader.ReadString( ); return Int32.Parse( s ); } } private static void HandleConnect( BinaryReader reader, BinaryWriter writer, NetworkStream socketStream, Socket connection ) { PrologInterface sharp = new PrologInterface( ); ArrayList agentClauses = new ArrayList( ); string next; while( !( next = reader.ReadString( ) ).Equals( "!claims." ) ) { Console.Out.WriteLine( "received: " + next ); agentClauses.Add( next ); sharp.setPredicate( new DcaAssertNoCopy_1( SymbolTerm.makeSymbol( next ), new ReturnCs( sharp ) ) ); sharp.call( ); } Console.Out.WriteLine( "now resolving..." ); sharp.setPredicate( new ResolveAll_2( new CsObjectTerm( reader ), new CsObjectTerm( writer ), new ReturnCs( sharp ) ) ); sharp.call( ); writer.Write( "ok." ); Console.Out.WriteLine( "ok." ); try { reader.Close( ); } catch { } try { writer.Close( ); } catch { } try { socketStream.Close( ); } catch { } try { connection.Close( ); } catch { } Console.Out.WriteLine( "now resetting all..." ); sharp.setPredicate( new ResetAllAgents_0( new ReturnCs( sharp ) ) ); sharp.call( ); } private static void RunServer( ) { TcpListener listener = new TcpListener( 6000 ); Socket connection; NetworkStream socketStream; BinaryWriter writer; BinaryReader reader; string msg; try { //listener = new TcpListener( 6000 ); listener.Start( ); while( true ) { connection = listener.AcceptSocket( ); socketStream = new NetworkStream( connection ); writer = new BinaryWriter( socketStream ); reader = new BinaryReader( socketStream ); try { msg = reader.ReadString( ); if( msg.StartsWith( "assert" ) ) { DoAssert( Strip( msg ) ); } else if( msg.StartsWith( "retract" ) ) { DoRetract( Strip( msg ) ); } else if( msg.Equals( "connect." ) ) { Console.Out.WriteLine( "connect." ); HandleConnect( reader, writer, socketStream, connection ); } else if( msg.Equals( "disconnect." ) ) { continue; } } catch( Exception ) { } finally { try { reader.Close( ); } catch { } try { writer.Close( ); } catch { } try { socketStream.Close( ); } catch { } try { connection.Close( ); } catch { } //try { listener.Stop( ); } catch { } System.Console.Out.WriteLine( "closed connection." ); } } } catch( Exception e ) { Console.WriteLine( "Error in runServer:\n" + e ); } finally { listener.Stop( ); } } } }