/*-------------------------------------------------------------*/ /* An NCL program for recognition of geometric figures */ /* (C) 1993 Zdravko Markov, II-BAS */ /*-------------------------------------------------------------*/ /* DESCRIPTION: ----------- This program illustrates the use of NCL for recognition of simple geometric figures. The edges of the figures are represented by free nodes in the following form: edge(Vertex1,Vertex2,Slope,Length) The shared variables among the free nodes represent the common vertices and the geometric constraints (equal lengths and slopes of some edges). The spreading activation nodes represent the classes of figures. The variables, included in the spreading activation nodes represent the connections between vertices and classes of figures they belong to. The program is executed by specifying the edges of instances of geometric figures as goals in NCL/Prolog queries. The corresponding class is obtained through a goal in these queries which unifies the free node "figure". Besides the concept nodes representing the classes of figures, a spreading activation node for calculating perpendicularity is also included. This node makes the net-clause look like a connectionist network. Its purpose is to split the geometric figures into two classes - perpendicular (square and rectangle) and non-perpendicular (rhombus and parallelogram). The node is activated when net-variables S1 and S2 (representing the slopes of the corresponding edges) are bound. If the condition for perpendicularity is present, then procedure "perp" binds net-variable P, thus activating the perpendicular classes and suppressing the non-perpendicular ones (through the inhibitory connection ~P). REFERENCE: ---------- Markov, Z. & Ch. Dichev. The Net-Clause Language - A Tool for Data-Driven Inference, In: Logics in AI, Proceedings of European Workshop JELIA'90, Amsterdam, The Netherlands, September 1990, LNCS, Vol.478, Springer-Verlag, 366-385. /*-------------------------------------------------------------*/ /* Edges of geometric figures */ edge(A,B,S1,L1): edge(B,C,S2,L1): edge(C,D,S1,L1): edge(D,A,S2,L1): edge(B,E,S2,L2): edge(E,F,S1,L1): edge(F,A,S2,L2): edge(E,G,S3,L3): edge(G,A,S4,L4): /* For storing the name of the recognized figure */ figure(Fig): /* General case of a four-side figure */ node(A,B,E,G,4,figure(four_side_figure)): /* Splitting figure into two classes */ node(S1,S2,2,perp(S1,S2,P)): /* Non-perpendicular figures */ node(A,B,E,F,~P,4,figure(parallelogram)): node(A,B,C,D,~P,4,figure(rhombus)): /* Perpendicular figures */ node(A,B,E,F,P,5,figure(rectangular)): node(A,B,C,D,P,5,figure(square)). /* A Prolog procedure for calculating perpendicularity */ perp(X,Y,true):-0 is (X-Y) mod 90,!. perp(_,_,_). /*-------------------------------------------------------------*/ /* EXAMPLES: */ /*-------------------------------------------------------------*/ /* Instances of figures */ f1:-edge(1,2,0,20),edge(2,3,45,30),edge(3,4,0,20),edge(4,1,45,30). f2:-edge(1,2,0,20),edge(2,3,90,20),edge(3,4,0,20),edge(4,1,90,20). f3:-edge(1,2,0,20),edge(2,3,50,20),edge(3,4,0,20),edge(4,1,50,20). f4:-edge(1,2,0,20),edge(2,3,90,30),edge(3,4,0,20),edge(4,1,90,30). f5:-edge(1,2,10,20),edge(2,3,30,40),edge(3,4,50,60),edge(4,1,70,80). /* Example queries: ?- f1,figure(X). X=parallelogram All-solution queries deliver the corresponding class and all superclasses too. For example: ?- setof(X,(f1,figure(X)),L). X=_1 L=[parallelogram,four_side_figure] ?- setof(X,(f2,figure(X)),L). X=_1 L=[square,rectangular,four_side_figure,rhombus] */