@cakcan: I honestly don't know what you are trying to do. I get the vague sense that you are trying to compare an observation against another. See if below makes any sense to you.
The output has all the combination of each observation (whose obs number indicated by i) compared against another (j), including itself. Given the pair of observations, then each of the three variables are compared: first var of the ith obs compared against the first var of the jth obs, and so on.
The results of the comparisons are simply summarized by the code variable, where 1 means match and 0 means no-match. For instance, the code value of 100 indicates that the first variable value of the ith observation matched with the first variable value of the jth observation, but the second and the third variable values did not. Then using a format, the code is translated into type. Hope this helps a bit.
[pre]
/* test data */
data one;
input i (i1 i2 i3) (:$1.);
cards;
1 A B C
2 A B D
3 X B C
4 X B Y
;
run;
/* full join by itself */
data two;
set one nobs=nobs;
do point = 1 to nobs;
set one(rename=(i=j i1=j1 i2=j2 i3=j3)) point=point;
output;
end;
run;
/* generate type */
proc format;
value $type
"111" = "line extention"
"110" = "brand extension"
"011" = "new category to brand"
"010" = "new brand"
other = "blank";
run;
data three;
set two;
code = cats(i1=j1, i2=j2, i3=j3);
type = put(code,$type21.);
run;
/* check */
proc print data=three noobs;
var i j code type;
run;
/* on lst
i j code type
1 1 111 line extention
1 2 110 brand extension
1 3 011 new category to brand
1 4 010 new brand
2 1 110 brand extension
2 2 111 line extention
2 3 010 new brand
2 4 010 new brand
3 1 011 new category to brand
3 2 010 new brand
3 3 111 line extention
3 4 110 brand extension
4 1 010 new brand
4 2 010 new brand
4 3 110 brand extension
4 4 111 line extention
*/
[/pre]